先确认/sys/class/pwm/下pwmchipn目录,再cat npwm查通道数、echo n > export导出通道,最后通过period(ns)、duty_cycle(ns)和enable配置pwm输出。

sysfs路径怎么找对PWM设备
Linux内嵌的PWM控制器(如i.MX、AM335x、RK系列)通常在/sys/class/pwm/下暴露接口,但具体子目录名取决于pwmchip编号和channel号。常见误区是直接进/sys/class/pwm/pwmchip0/就以为能用——其实得先确认该chip是否已export,且对应硬件通道已启用。
实操建议:
- 用
ls /sys/class/pwm/看有哪些pwmchipN; - 检查
cat /sys/class/pwm/pwmchipN/name确认控制器型号(比如imx-pwm或rockchip-pwm); - 查设备树源码或
dmesg | grep pwm,确认哪个pwmchip对应你板子上实际接了负载的PWM引脚(例如pwmchip2可能对应GPIO12,而pwmchip0被禁用); - 若
/sys/class/pwm/pwmchipN/pwmN:0不存在,需先echo 0 > /sys/class/pwm/pwmchipN/export(0是channel索引,非GPIO编号)。
export后怎么配置周期和占空比
sysfs控制PWM本质是写三个关键文件:period、duty_cycle、enable,单位全是纳秒(ns),不是Hz或百分比。最容易出错的是单位混淆——比如想输出1kHz(周期1ms),却写成echo 1000 > period,实际应写echo 1000000 > period。
实操建议:
- 周期必须先设,且
duty_cycle不能超过period,否则写入失败并报Invalid argument; - 设完
period和duty_cycle后,再echo 1 > enable,顺序反了会静默失败; - 若需动态调占空比,只需重复写
duty_cycle和enable(enable保持1即可); - 注意权限:嵌入式rootfs常默认只允许root写,普通用户需加
udev规则或改目录权限。
为什么写完enable没波形输出
常见现象:echo 1 > enable返回成功,但示波器测不到信号。问题往往不在sysfs本身,而在底层约束未满足。
排查要点:
- 确认pwmchip对应的时钟已使能(
cat /sys/kernel/debug/clk/pwm_clk/prepare应为1); - 检查pinmux是否把该引脚配置为PWM功能(例如AM335x需在
am335x-boneblack.dts里配pinctrl-0 = ;); - 某些SoC(如i.MX6ULL)要求先设
enable=0再设参数,否则寄存器锁死; - 用
cat /sys/class/pwm/pwmchipN/pwmN:0/period等回读值,确认写入真正生效(有些驱动不校验,写错也无提示)。
C++程序里怎么安全操作sysfs节点
直接用system("echo 1000000 > /sys/class/pwm/...")风险高:路径拼错、权限不足、无错误反馈。更可靠的是用POSIX文件I/O逐个open/write/close,并检查返回值。
关键点:
- 所有sysfs写操作必须用
O_WRONLY打开,且每次write后要close(部分驱动依赖close触发更新); - 写
period前先读当前值,避免因驱动限制导致写入被截断(例如某些pwmchip最小周期为100ns,写90ns会被自动拉到100ns); - 用
std::ofstream时务必检查fail()和bad(),不要只看is_open(); - 避免多线程同时操作同一pwm通道——sysfs无锁,竞态会导致参数错乱。
复杂点在于,不同SoC的pwmchip行为差异大:有的支持capture,有的不支持enable toggle,有的要求period必须是某个基频的整数倍。动手前一定查清你用的pwmchip驱动源码(drivers/pwm/pwm-*.c)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











