RK3566开发板PWM驱动实战:从设备树配置到Shell调试全解析
刚拿到RK3566开发板时,面对密密麻麻的芯片手册和零散的社区资料,配置一个简单的PWM外设可能会让不少开发者感到无从下手。本文将以PWM14_M1为例,带你完整走通从设备树修改到命令行调试的全流程,过程中会特别标注那些官方文档没写清楚但实际开发中一定会遇到的"坑"。
1. 理解RK3566的PWM子系统架构
RK3566的PWM控制器采用多通道设计,每个PWM控制器可以支持多个通道。以PWM14为例,它属于PWM3控制器组,硬件地址从0xfe700020开始。与STM32等MCU不同,Linux环境下配置PWM需要先理解几个关键概念:
- 设备树(DTS):描述硬件资源配置的静态定义文件
- PWM子系统:Linux内核提供的统一接口层
- Sysfs接口:用户空间控制PWM的调试入口
注意:RK3566的PWM通道编号与硬件地址的对应关系容易混淆,建议先通过
/sys/kernel/debug/pwm确认实际映射关系
芯片手册中容易忽略的关键参数:
| 参数 | 说明 | 典型值示例 |
|---|---|---|
| CLK_PWM3 | PWM3控制器时钟源 | 24MHz |
| PCLK_PWM3 | PWM3外设总线时钟 | 100MHz |
| pinctrl-0 | 管脚复用配置 | &pwm14m1_pins |
2. 设备树配置实战
2.1 定位正确的DTS文件
RK3566开发板通常有两个关键设备树文件需要修改:
- 通用芯片定义:
rk3568.dtsi(路径:arch/arm64/boot/dts/rockchip/) - 板级配置:如
rk3566-rk817-tablet.dts
# 在kernel源码目录下快速查找 find arch/arm64/boot/dts/rockchip -name "*rk3566*.dts"2.2 修改PWM节点配置
在rk3568.dtsi中找到PWM14的基础定义,确保包含以下关键属性:
pwm14: pwm@fe700020 { compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xfe700020 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm14m1_pins>; clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>; clock-names = "pwm", "pclk"; status = "disabled"; };然后在板级DTS中启用该节点:
&pwm14 { status = "okay"; // 重要:某些开发板需要显式指定pinctrl pinctrl-0 = <&pwm14m1_pins>; };常见坑点排查:
- 如果修改后不生效,检查是否有其他DTS覆盖了你的配置
- 使用
fdtdump工具验证编译后的dtb是否包含你的修改:fdtdump /boot/dtbs/$(uname -r)/rockchip/rk3566-your-board.dtb | grep pwm14
3. 内核编译与烧写技巧
3.1 选择性编译内核模块
为节省时间,可以只重新编译设备树部分:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs -j$(nproc)3.2 烧写验证流程
生成新的boot.img:
mkimage -f kernel.its kernel.img通过Rockchip开发工具烧写:
rkdeveloptool write 0x200000 kernel.img
提示:开发阶段建议保留串口调试连接,可实时查看内核启动日志
4. Shell调试完整流程
4.1 确认PWM设备注册
# 查看已注册的PWM控制器 cat /sys/kernel/debug/pwm # 典型输出示例 platform/fe700020.pwm, 1 PWM device pwm-0 ((null)): period: 0 ns duty: 0 ns polarity: inverse4.2 配置PWM参数
# 进入PWM控制目录 cd /sys/class/pwm/pwmchip2 # 导出PWM通道 echo 0 > export # 配置参数 cd pwm0 echo 10000 > period # 设置周期为10us (100kHz) echo 5000 > duty_cycle # 占空比50% echo normal > polarity # 正常极性 echo 1 > enable # 启动输出调试技巧:
- 用示波器测量实际波形时,如果无输出:
- 检查
dmesg | grep pwm是否有错误日志 - 确认GPIO复用配置正确:
cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep gpio3
- 检查
5. 进阶:自动化控制脚本
创建/usr/local/bin/pwm_ctrl.sh:
#!/bin/bash PWM_CHIP=${1:-2} PWM_CHAN=${2:-0} PERIOD_NS=${3:-10000} DUTY_NS=${4:-5000} PWM_PATH="/sys/class/pwm/pwmchip${PWM_CHIP}/pwm${PWM_CHAN}" # 初始化PWM if [ ! -d "$PWM_PATH" ]; then echo $PWM_CHAN > /sys/class/pwm/pwmchip${PWM_CHIP}/export sleep 0.1 fi # 配置参数 echo $PERIOD_NS > "$PWM_PATH/period" echo $DUTY_NS > "$PWM_PATH/duty_cycle" echo normal > "$PWM_PATH/polarity" echo 1 > "$PWM_PATH/enable"使用示例:
# 控制PWM14输出1kHz,30%占空比 pwm_ctrl.sh 2 0 1000000 3000006. 硬件连接验证要点
当软件配置正确但硬件无输出时,按以下步骤排查:
电压测量:
- 确认PWM引脚电压在使能前后有变化
- 默认GPIO电压应为3.3V
示波器检测:
- 观察波形频率是否与配置一致
- 检查占空比精度(RK3566的PWM分辨率约为4.17ns)
替代方案测试:
- 尝试其他PWM通道排除硬件故障
- 用LED串联电阻直接测试(PWM频率建议设置在100Hz-1kHz区间)
在Firefly-RK3566开发板上,PWM14_M1默认对应GPIO3_C6引脚,位置在40针扩展口的第33脚。实际项目中遇到过一个典型案例:某散热风扇需要先给使能信号才能响应PWM控制,这种硬件特性往往不会体现在芯片手册中