我需要为linux内核实现PWM模块,它应该是高分辨率(在我的400MHz ARM cpu上将超过10kHz) 任何人都可以给我一个建议,我可以用于此目的吗? 内核版本是2.6.28.9。 设备没有硬件PWM驱动程序。 现在我使用一个内核定时器,其频率由CONFIG_HZ设置。这个配置的默认值是100HZ,但对我来说太少了,最大值是4kHZ,但这还不够
答案 0 :(得分:1)
Pulse-width modulation在软件中非常非常难。理论上,你所要做的就是在你的CPU中找到一个具有足够好分辨率的计时器,连接一个IRQ处理程序并启动它。
如果你看一下时钟,你就不能在400 MHz CPU上做10 kHz PWM - 你每次脉冲就会有400000/10 = 40000个CPU周期,这肯定够了吗?
也许不是。 linux内核使用中断本身来进行内核调用。然后你有其他中断(DMA,NMI s,其他计时器,...)。根据定时器中断的优先级,其中一些可以阻止它。这意味着网络操作或其他东西可能会延迟您的IRQ处理程序。如果您正在使用Linux内核API来处理中断,那么您会遇到更多问题:内核不会调用您的处理程序。相反,真正的IRQ处理程序将收集有关中断的一些信息,并将其作为任务附加到链。
最终,内核将查看该链并处理其中的任务。
另一个问题是CPU也不会立即响应IRQ。有些操作码你不能中断。
这会导致很多抖动。
如果你想尝试一下,那么你应该在汇编程序中编写自己的IRQ处理程序,它执行所有处理 - 获取IRQ并写入新的输出值。不要使用标准的linux中断API。然后,您必须为此计时器禁用中断API(或者内核可能会删除您的处理程序)。
你必须使用一个在你的CPU中具有非常高优先级的计时器 - 任何可以延迟它的东西都会毁了你的一天。
即使您有40K的CPU周期:总有其他软件也需要咬一口。所以你可能无法运行任何其他东西。
答案 1 :(得分:0)
“如果你想要一些精确的时序,请使用硬件PWM。软件将有太多的偏差,抖动等。即使付出巨大的努力,它也远远不是好的(不是完美的)。”
上述答案并不完全正确,即使它显示了PWM的一些问题:
问题在于,无论输出信号来自硬件PWM发生器还是来自软件控制的GPIO,应用程序必须在单个PWM周期内执行所有计算。 否则,抖动将作为一个incorect平均PWM值或不正确的平均信号相移观察到。
换句话说,使用HW PWM的唯一好处是计算可以与PWM脉冲边沿异步完成,但它们必须与PWM周期的开始/结束同步。