news 2026/7/6 6:48:18

OpenHarmony 5.1.0 南向开发实战:基于RK3568开发板移植3个关键驱动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenHarmony 5.1.0 南向开发实战:基于RK3568开发板移植3个关键驱动

OpenHarmony 5.1.0 南向开发实战:基于RK3568开发板移植3个关键驱动

RK3568作为当前主流的嵌入式处理器之一,在智能终端设备领域有着广泛应用。本文将深入探讨如何在OpenHarmony 5.1.0系统上为RK3568开发板移植三个关键硬件驱动:GPIO控制器驱动、I2C总线驱动和PWM控制器驱动。通过完整的代码示例和详细的移植步骤,帮助开发者快速掌握OpenHarmony南向开发的核心技术。

1. 开发环境准备与基础配置

在开始驱动移植前,需要搭建完整的开发环境。OpenHarmony 5.1.0对开发工具链和系统组件进行了多项优化,特别是对RK3568芯片的支持更加完善。

1.1 硬件准备清单

  • RK3568开发板(建议使用官方标准开发板)
  • Type-C数据线(用于烧录和调试)
  • 5V/3A电源适配器
  • 调试用串口转USB模块(如CH340)
  • 可选:J-Link调试器(用于深度调试)

1.2 软件环境配置

# 安装基础工具链 sudo apt-get install -y git python3.8 python3-pip # 获取OpenHarmony 5.1.0代码 repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony-5.1.0-Release --no-repo-verify repo sync -c repo forall -c 'git lfs pull' # 安装编译依赖 ./build/prebuilts_download.sh

注意:建议使用Ubuntu 20.04 LTS作为开发主机系统,确保环境一致性。编译过程需要至少16GB内存和100GB磁盘空间。

1.3 内核配置调整

RK3568使用Linux 5.10内核,需要进行针对性配置:

# 进入内核配置界面 cd kernel/linux-5.10 make ARCH=arm64 menuconfig # 关键配置项 CONFIG_GPIO_ROCKCHIP=y CONFIG_I2C_ROCKCHIP=y CONFIG_PWM_ROCKCHIP=y

保存配置后,需要更新到设备树文件。RK3568的设备树位于kernel/linux-5.10/arch/arm64/boot/dts/rockchip/rk3568.dtsi

2. GPIO控制器驱动移植

GPIO驱动是硬件控制的基础,RK3568的GPIO控制器具有丰富的功能和灵活的配置方式。

2.1 驱动框架分析

OpenHarmony的GPIO子系统采用分层设计:

  • 硬件抽象层(HAL):drivers/peripheral/gpio/hal
  • 内核接口层:drivers/peripheral/gpio/linux
  • 用户态接口:通过/dev/gpio设备节点提供操作接口

2.2 关键代码实现

创建drivers/peripheral/gpio/chips/gpio_rockchip.c

#include "gpio_core.h" #define RK3568_GPIO_BANKS 4 #define GPIO_PER_BANK 32 struct rockchip_gpio_chip { void __iomem *reg_base; struct GpioCntlr cntlr; int irq; }; static int RockchipGpioSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir) { struct rockchip_gpio_chip *chip = container_of(cntlr, struct rockchip_gpio_chip, cntlr); unsigned long flags; u32 val; spin_lock_irqsave(&chip->lock, flags); val = readl(chip->reg_base + GPIO_SWPORT_DDR); if (dir == GPIO_DIR_OUT) val |= BIT(gpio); else val &= ~BIT(gpio); writel(val, chip->reg_base + GPIO_SWPORT_DDR); spin_unlock_irqrestore(&chip->lock, flags); return 0; } static const struct GpioMethod g_method = { .request = NULL, .release = NULL, .write = RockchipGpioWrite, .read = RockchipGpioRead, .setDir = RockchipGpioSetDir, .getDir = RockchipGpioGetDir, .toIrq = NULL, }; int RockchipGpioInit(struct HdfDeviceObject *device) { struct rockchip_gpio_chip *chip; int ret; chip = (struct rockchip_gpio_chip *)OsalMemCalloc(sizeof(*chip)); chip->reg_base = OsalIoRemap(0xFE720000, 0x1000); chip->cntlr.device = device; chip->cntlr.ops = &g_method; chip->cntlr.count = RK3568_GPIO_BANKS * GPIO_PER_BANK; ret = GpioCntlrAdd(&chip->cntlr); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: add gpio controller failed", __func__); return ret; } return HDF_SUCCESS; }

2.3 驱动配置与测试

vendor/hihope/rk3568/hdf_config/device_info.hcs中添加配置:

gpio_config { controller_0x1200 :: gpio_controller { match_attr = "rockchip_gpio_driver"; gpioDir = 0xFE720000; gpioRegBase = 0xFE720000; gpioRegSize = 0x1000; irqNum = 100; irqShare = 1; } }

测试命令:

cat /sys/kernel/debug/gpio # 查看GPIO状态 echo 123 > /sys/class/gpio/export # 导出GPIO123 echo out > /sys/class/gpio/gpio123/direction # 设置为输出 echo 1 > /sys/class/gpio/gpio123/value # 输出高电平

3. I2C总线驱动移植

I2C总线是连接各类传感器的关键接口,RK3568内置了多个I2C控制器。

3.1 驱动框架分析

OpenHarmony的I2C架构包含:

  • HDF驱动框架层:提供统一设备模型
  • 平台驱动层:实现具体控制器操作
  • 设备驱动层:对接具体I2C设备

3.2 关键代码实现

创建drivers/peripheral/i2c/chips/i2c_rockchip.c

#include "i2c_core.h" #define RK3568_I2C_SPEED_STANDARD 100000 #define RK3568_I2C_SPEED_FAST 400000 struct rockchip_i2c { struct I2cCntlr cntlr; void __iomem *regs; unsigned int irq; unsigned int speed; }; static int RockchipI2cTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int num) { struct rockchip_i2c *i2c = container_of(cntlr, struct rockchip_i2c, cntlr); int ret = 0; /* 配置I2C控制器 */ writel(I2C_CON_EN | I2C_CON_MOD_TX | I2C_CON_START, i2c->regs + I2C_CON); for (int i = 0; i < num; i++) { if (msgs[i].flags & I2C_M_RD) { /* 读操作处理 */ writel(msgs[i].addr << 1 | 1, i2c->regs + I2C_TXD); writel(I2C_CON_EN | I2C_CON_MOD_TX | I2C_CON_START, i2c->regs + I2C_CON); /* 读取数据 */ for (int j = 0; j < msgs[i].len; j++) { if (j == msgs[i].len - 1) writel(I2C_CON_EN | I2C_CON_MOD_RX | I2C_CON_STOP, i2c->regs + I2C_CON); else writel(I2C_CON_EN | I2C_CON_MOD_RX, i2c->regs + I2C_CON); msgs[i].buf[j] = readl(i2c->regs + I2C_RXD); } } else { /* 写操作处理 */ writel(msgs[i].addr << 1, i2c->regs + I2C_TXD); writel(I2C_CON_EN | I2C_CON_MOD_TX | I2C_CON_START, i2c->regs + I2C_CON); for (int j = 0; j < msgs[i].len; j++) { writel(msgs[i].buf[j], i2c->regs + I2C_TXD); writel(I2C_CON_EN | I2C_CON_MOD_TX, i2c->regs + I2C_CON); } writel(I2C_CON_EN | I2C_CON_MOD_TX | I2C_CON_STOP, i2c->regs + I2C_CON); } } return ret; } static const struct I2cMethod g_rockchipI2cMethod = { .transfer = RockchipI2cTransfer, }; int RockchipI2cInit(struct HdfDeviceObject *device) { struct rockchip_i2c *i2c; int ret; i2c = (struct rockchip_i2c *)OsalMemCalloc(sizeof(*i2c)); i2c->regs = OsalIoRemap(0xFDD40000, 0x1000); i2c->cntlr.priv = i2c; i2c->cntlr.methods = &g_rockchipI2cMethod; i2c->cntlr.busId = 0; i2c->speed = RK3568_I2C_SPEED_STANDARD; ret = I2cCntlrAdd(&i2c->cntlr); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: add i2c controller failed", __func__); return ret; } return HDF_SUCCESS; }

3.3 设备树配置

kernel/linux-5.10/arch/arm64/boot/dts/rockchip/rk3568.dtsi中添加:

i2c0: i2c@fdd40000 { compatible = "rockchip,rk3568-i2c"; reg = <0x0 0xfdd40000 0x0 0x1000>; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>; clock-names = "i2c", "pclk"; pinctrl-names = "default"; pinctrl-0 = <&i2c0_xfer>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; };

3.4 测试验证

使用i2c-tools进行测试:

i2cdetect -y 0 # 扫描I2C0总线上的设备 i2cget -y 0 0x50 0x00 # 读取I2C设备0x50的0x00寄存器 i2cset -y 0 0x50 0x00 0x12 # 向I2C设备0x50的0x00寄存器写入0x12

4. PWM控制器驱动移植

PWM驱动在电机控制、背光调节等场景中至关重要,RK3568提供了多路PWM输出。

4.1 驱动框架分析

OpenHarmony的PWM驱动架构:

  • 硬件抽象层:drivers/peripheral/pwm/hal
  • 平台驱动层:实现具体PWM控制器操作
  • 服务层:提供统一的用户态接口

4.2 关键代码实现

创建drivers/peripheral/pwm/chips/pwm_rockchip.c

#include "pwm_core.h" #define RK3568_PWM_CHANNELS 4 #define PWM_REG_CNTR 0x00 #define PWM_REG_PERIOD_HPR 0x04 #define PWM_REG_DUTY_LPR 0x08 #define PWM_REG_CTRL 0x0c struct rockchip_pwm { struct PwmDev dev; void __iomem *base; struct clk *clk; }; static int RockchipPwmSetConfig(struct PwmDev *pwm, struct PwmConfig *config) { struct rockchip_pwm *chip = (struct rockchip_pwm *)pwm->priv; u64 div, val; u32 clk_rate; clk_rate = clk_get_rate(chip->clk); div = (u64)clk_rate * config->period; do_div(div, NSEC_PER_SEC); writel(div, chip->base + PWM_REG_PERIOD_HPR); val = (u64)div * config->dutyCycle; do_div(val, 100); writel(val, chip->base + PWM_REG_DUTY_LPR); return 0; } static int RockchipPwmEnable(struct PwmDev *pwm) { struct rockchip_pwm *chip = (struct rockchip_pwm *)pwm->priv; u32 val; val = readl(chip->base + PWM_REG_CTRL); val |= PWM_ENABLE; writel(val, chip->base + PWM_REG_CTRL); return 0; } static const struct PwmMethod g_rockchipPwmOps = { .setConfig = RockchipPwmSetConfig, .enable = RockchipPwmEnable, .disable = RockchipPwmDisable, }; int RockchipPwmInit(struct HdfDeviceObject *device) { struct rockchip_pwm *pwm; int ret; pwm = (struct rockchip_pwm *)OsalMemCalloc(sizeof(*pwm)); pwm->base = OsalIoRemap(0xFE6E0000, 0x10); pwm->dev.method = &g_rockchipPwmOps; pwm->dev.priv = pwm; pwm->dev.device = device; ret = PwmDeviceAdd(&pwm->dev); if (ret != HDF_SUCCESS) { HDF_LOGE("%s: add pwm device failed", __func__); return ret; } return HDF_SUCCESS; }

4.3 设备树配置

rk3568.dtsi中添加PWM节点:

pwm0: pwm@fe6e0000 { compatible = "rockchip,rk3568-pwm"; reg = <0x0 0xfe6e0000 0x0 0x10>; clocks = <&cru CLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; #pwm-cells = <3>; status = "disabled"; };

4.4 测试验证

通过sysfs接口测试PWM:

echo 0 > /sys/class/pwm/pwmchip0/export # 导出PWM0 echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period # 设置周期为1ms echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle # 设置占空比为50% echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable # 启用PWM输出

5. 驱动调试与性能优化

驱动移植完成后,需要进行系统级调试和性能优化,确保驱动稳定可靠。

5.1 调试技巧与工具

常用调试命令:

dmesg | grep rockchip # 查看内核日志 cat /proc/interrupts # 查看中断统计 cat /proc/iomem | grep -i pwm # 查看内存映射

性能分析工具:

  • perf:分析驱动性能热点
  • ftrace:跟踪函数调用关系
  • systrace:系统级性能分析

5.2 常见问题解决

问题1:GPIO无法正确设置方向

  • 检查设备树中pinctrl配置
  • 验证寄存器映射地址是否正确
  • 确认GPIO是否被其他驱动占用

问题2:I2C通信失败

  • 使用示波器检查SCL/SDA信号
  • 确认从设备地址正确
  • 检查时钟配置和上拉电阻

问题3:PWM输出不稳定

  • 验证时钟源配置
  • 检查负载是否匹配
  • 调整死区时间配置

5.3 性能优化建议

  1. 中断优化

    • 使用线程化中断处理
    • 实现中断共享
    • 合理设置中断亲和性
  2. DMA传输

    • 对大数据量传输启用DMA
    • 合理设置DMA缓冲区对齐
  3. 电源管理

    • 实现runtime PM支持
    • 合理使用延迟工作队列
// DMA配置示例 void SetupDmaTransfer(struct device *dev) { struct dma_chan *chan; struct dma_slave_config config = {0}; chan = dma_request_chan(dev, "tx"); config.direction = DMA_MEM_TO_DEV; config.dst_addr = phys_addr; config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dmaengine_slave_config(chan, &config); dma_async_issue_pending(chan); }

通过以上完整的驱动移植过程和优化建议,开发者可以快速在RK3568开发板上构建稳定的OpenHarmony 5.1.0系统。这三个关键驱动的实现为后续外设开发奠定了坚实基础,开发者可以根据实际需求进一步扩展更多功能模块。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 6:45:56

MC74HC165A在嵌入式IO扩展中的高效应用与优化

1. 项目背景与核心价值在嵌入式系统开发中&#xff0c;IO扩展是永恒的话题。当我们需要监控数十个传感器信号或控制多个执行机构时&#xff0c;GPIO引脚数量往往成为瓶颈。传统解决方案要么选择更高端的MCU&#xff08;成本飙升&#xff09;&#xff0c;要么采用复杂的IO扩展芯…

作者头像 李华
网站建设 2026/7/6 6:44:30

3DS游戏格式转换终极指南:一键将.3ds文件变为可安装CIA

3DS游戏格式转换终极指南&#xff1a;一键将.3ds文件变为可安装CIA 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 还在为3…

作者头像 李华
网站建设 2026/7/6 6:43:05

在数据分析中,如何通过机器学习方法进行数据建模?

数据分析中机器学习建模方法综合调研报告 摘要 机器学习建模是当代数据分析体系的核心技术环节&#xff0c;将原始数据转化为可预测、可决策的智能系统。本报告基于多源网络调研与学术文献交叉验证&#xff0c;系统阐述了从问题定义到模型部署的完整建模流程&#xff0c;并深入…

作者头像 李华
网站建设 2026/7/6 6:42:01

Si5351A与ATSAME70Q21B实现高精度时钟管理方案

1. 项目背景与核心需求在嵌入式系统和数字电路设计中&#xff0c;稳定的时钟信号如同人体的脉搏&#xff0c;是确保系统正常运转的基础。无论是汽车电子中的ECU控制单元&#xff0c;还是工业自动化设备中的实时通信&#xff0c;都需要高精度的频率参考来同步各个模块的时序。传…

作者头像 李华
网站建设 2026/7/6 6:40:29

Havenlon|AI 时代的执行控制(一):审批通过,不等于执行安全

摘要在传统业务系统里&#xff0c;人们习惯把"审批通过"理解为一件高风险动作已经被控制住了。付款申请被批准&#xff0c;权限变更被同意&#xff0c;数据导出被审核&#xff0c;脚本执行被授权&#xff0c;流程走完之后&#xff0c;风险似乎就已经被消化。但这个判…

作者头像 李华