在开发过程中,难免会遇到需要SoC给外设输出稳定可调节时钟的需求,因此这里给出几种可实现的方案,基本能涵盖大多数需求。我这里的时钟频率需求为几Hz~几十KHz。
1、具有CLK输出功能的IOMUX
通过查看CLK手册、原理图和PCB图,RK3568开发板可以使用且引出的高频时钟为GPIO2_C1、GPIO3_B0,但其频率均为高频时钟,不符合驱动外设所需的几Hz~几十kHz的时钟频率。
2、可以考虑使用pwm口来实现
通过检查原理图和PCB图,发现开发板上的pwm均被占用,且有一部分没有引出io口,因此只能考虑通过软件的方式来实现,把一个gpio注册成pwm,随后在驱动中通过timer回调拉高拉低GPIO模拟时钟输出
3、软件上可以考虑使用主控的timer,在timer回调函数里拉高拉低GPIO来实现
参考设备树的pwm-gpio配置和pwm-gpio驱动
Documentation/devicetree/bindings/pwm/pwm-gpio.txt
drivers/pwm/pwm-gpio.c
添加到设备树的合适位置,可以参考Led-gpio的位置
pwm-gpio {
compatible = "pwm-gpio";
#pwm-cells = <3>;
pwm-gpio = <&gpio2 RK_PD5 GPIO_ACTIVE_HIGH>;
};
编辑kernel/arch/arm64/config/rockchip_linux_defconfig
打开下面的编译选项
CONFIG_PWM_GPIO=y
编译内核
烧录启动进入系统后
enable :写入 1 使能 pwm ,写入 0 关闭 pwm ;polarity :有 normal 或 inversed 两个参数选择,表示输出引脚电平翻转;duty_cycle :在 normal 模式下,表示一个周期内高电平持续的时间(单位:纳秒),在 reversed 模式下,表示一个周期中低电平持续的时间(单位:纳秒 ) ;period :表示 pwm 波的周期 ( 单位:纳秒 ) ;
通过下面的命令可以设置100K的时钟,示波器测试发现平均值大约为100K,频率并不稳定
cd /sys/class/pwm/pwmchip0/
echo 0 > export
cd pwm0
echo 10000 > period
echo 5000 > duty_cycle
echo normal > polarity
echo 1 > enable
修改频率测试,在80K及以下的时钟频率基本都是稳定可靠的,因为是通过GPIO拉高拉低实现的pwm波形,所以高频以后波形不稳定。
另外又在ping网络的情况下测试了时钟频率,因为网络是通过包的形式发送,会产生较高频率的中断,测试发现ping网络对各频率的时钟没有明显的影响。随后又在cpu压测下测试了时钟频率,top命令可以看到四核的cpu占用率基本100%。
测试结果发现在10KHz以上的频率,会明显观测到影响波形的输出,频率越高越明显。
在5KHz时,则没有明显的异常波形
另外如果想在内核空间去调用可以参考drivers/pwm/pwm-gpio.c,在内核实现pwm的调用