1、PWM介绍
参考博客:《ARM芯片开发(S5PV210芯片)——定时器、看门狗、RTC》;
2、配置pwm功能的方法
(1)内核层:内核代码里有pwm子系统,里面有pwm相关函数接口,如果是驱动代码里要操作pwm就需要调用pwm子系统的函数接口;
(2)脚本操作:pwm子系统会向sys子系统注册pwm资源,可以通过脚本来控制pwm;
(3)代码里读写文件的方式操作:操作流程和用脚本控制是一样的,区别就是要用open、write、read、close等函数来操作文件;
总结:内核层操作pwm要使用pwm子系统提供的接口;应用层可以用脚本也可以用读写文件的方式操作pwm;
3、/sys/class/pwm
~ # ls /sys/class/pwm/ -l
total 0
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip0 -> ../../devices/platform/fdd70000.pwm/pwm/pwmchip0
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip1 -> ../../devices/platform/fdd70010.pwm/pwm/pwmchip1
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip2 -> ../../devices/platform/fdd70020.pwm/pwm/pwmchip2
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip3 -> ../../devices/platform/fe6f0020.pwm/pwm/pwmchip3
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip4 -> ../../devices/platform/fe6f0030.pwm/pwm/pwmchip4
文件夹下都是已经使能的pwm控制器,并且都是符号链接;
4、/sys/devices/platform
~ # ls /sys/devices/platform/* | grep ".pwm"
/sys/devices/platform/fdd70000.pwm:
/sys/devices/platform/fdd70010.pwm:
/sys/devices/platform/fdd70020.pwm:
/sys/devices/platform/fe6f0020.pwm:
/sys/devices/platform/fe6f0030.pwm:
platform文件下下面都是platform总线里注册的设备,其中就包括已经使能的pwm控制器;
5、设备树里pwm配置
pwm0: pwm@fdd70000 {
compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xfdd70000 0x0 0x10>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm0m0_pins>;
clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>;
clock-names = "pwm", "pclk";
status = "disabled";
};
pwm1: pwm@fdd70010 {
compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xfdd70010 0x0 0x10>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm1m0_pins>;
clocks = <&pmucru CLK_PWM0>, <&pmucru PCLK_PWM0>;
clock-names = "pwm", "pclk";
status = "disabled";
};
······
pwm15: pwm@fe700030 {
compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xfe700030 0x0 0x10>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm15m0_pins>;
clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
clock-names = "pwm", "pclk";
status = "disabled";
};
设备树里包含Soc里所以的pwm控制器资源。RK3568总共有16个pwm控制器,可以输出16路pwm;
6、/proc/device-tree
~ # ls /proc/device-tree/pwm@f
pwm@fdd70000/ pwm@fe6e0000/ pwm@fe6f0000/ pwm@fe700000/
pwm@fdd70010/ pwm@fe6e0010/ pwm@fe6f0010/ pwm@fe700010/
pwm@fdd70020/ pwm@fe6e0020/ pwm@fe6f0020/ pwm@fe700020/
pwm@fdd70030/ pwm@fe6e0030/ pwm@fe6f0030/ pwm@fe700030/
# 7、查看pwm15的状态
~ # cat /proc/device-tree/pwm@fe700030/status
disabled
(1)/proc/device-tree/文件夹下是设备树里包含的资源,和设备树是完全对应的;
(2)可以在/proc/device-tree/文件夹下查看对应的硬件资源,比如状态status、名字nane、匹配信息compatible等等;
补充:对设备树不熟悉的参考博客:《https://blog.csdn.net/weixin_42031299/article/details/125813060》;
8、内核里各处pwm控制器信息的联系
(1)设备树文件里包含芯片所有的pwm资源,但是有的pwm控制器是被disable的;
(2)/proc/device-tree/文件夹下是内核对设备数文件的解析,和设备树文件里的内容是一一对应的,可以通过该文件夹去查看硬件状态;
(3)/sys/devices/platform/文件夹下显示的是注册到platform总线的pwm设备,只有状态是"okay"的pwm控制器才会被注册到platform总线;
(4)/sys/class/pwm/是符号链接,方便查看的;
9、配置pwm功能步骤
(1)在设备树里开启对应的pwm功能;
(2)确认是否真的使能pwm功能,有可能该引脚已经被复用成其他功能,需要先关闭该引脚的其他功能;
(3)配置pwm波的周期、占空比、极性等操作;
(4)使能pwm引脚,测量pwm引脚是否输出正确的pwm波;
10、配置pwm11为例
10.1、在设备树里开启pwm11
# 一般是默认关闭的
pwm11: pwm@fe6f0030 {
compatible = "rockchip,rk3568-pwm", "rockchip,rk3328-pwm";
reg = <0x0 0xfe6f0030 0x0 0x10>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
#pwm-cells = <3>;
pinctrl-names = "active";
pinctrl-0 = <&pwm11m0_pins>;
clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
clock-names = "pwm", "pclk";
status = "disabled";
};
# 在设备树后面追加,使能pwm11
&pwm11 {
pinctrl-0 = <&pwm11m0_pins>;
status = "okay";
pinctrl-names = "active";
};
(1)在设备里将pwm11使能,重新烧录内核后,可在/proc/device-tree/查看pwm11的状态——“cat /proc/device-tree/pwm@fe6f0030/status”;
(2)需要注意当前pwm11是使用的哪组引脚,从上面的原理图可在pwm11使用的m0组引脚,需要配置pinctrl-0选项;涉及pinctrl子系统,这里不详细介绍;
10.2、确认pwm11是否开启
~ # ls -l /sys/class/pwm/
total 0
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip0 -> ../../devices/platform/fdd70000.pwm/pwm/pwmchip0
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip1 -> ../../devices/platform/fdd70010.pwm/pwm/pwmchip1
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip2 -> ../../devices/platform/fdd70020.pwm/pwm/pwmchip2
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip3 -> ../../devices/platform/fe6f0020.pwm/pwm/pwmchip3
lrwxrwxrwx 1 root root 0 Jan 1 00:00 pwmchip4 -> ../../devices/platform/fe6f0030.pwm/pwm/pwmchip4 #这就是pwm11
(1)查看/sys/class/pwm/文件夹,看看是否有pwm11;
10.3、通过sys文件系统来控制pwm11
#配置GPIO3_B6为pwm功能
devmem 0xFDC6004C 32 0xffff0500
# GPIO3_B6
cd /sys/class/pwm/pwmchip4/ > /dev/null 2>&1
echo 0 > export
cd pwm0 > /dev/null 2>&1
echo 26000 > period # 配置周期
echo 13000 > duty_cycle # 配置占空比
echo normal > polarity # 配置极性
echo 1 > enable # 使能pwm
cd - > /dev/null 2>&1
(1)首先查阅数据手册,配置GPIO3_B6为pwm功能;
(2)通过sys文件系统来控制pwm11;
(3)使用open、read、write、close等接口操作pwm,参考博客:《Linux应用开发【第十一章】PWM编程应用开发》;
推荐
给大家推荐一个学校嵌入式知识的网站,博主在大学时候学习嵌入式知识、找工作的时候都在用这个网站,网站里有C语言、Linux等等的笔试题、面试常问问题等等知识,无论是学习基础知识、面试刷题、交流工作经验都是不错的选择。大家一起进步,欢迎留言交流。
链接:学习神器跳转