【问题标题】:Sofware pwm as linux kernel module软件 pwm 作为 linux 内核模块
【发布时间】:2015-06-05 10:47:01
【问题描述】:

我需要为 linux 内核实现 PWM 模块,它应该是高分辨率的(在我的 400MHz ARM cpu 上会超过 10kHz) 谁能给我一个建议,我可以为此目的使用什么? 内核版本为 2.6.28.9。 设备没有硬件 PWM 驱动程序。 现在我使用一个内核定时器,其频率由 CONFIG_HZ 设置。这个配置的默认值是100HZ,但对我来说太小了,最大值是4kHZ,但这仍然不够

【问题讨论】:

  • 什么是“pwm”?那是哪个CPU?它有HPET吗? en.wikipedia.org/wiki/High_Precision_Event_Timer
  • 如果您想要更精确的时序,请使用硬件 PWM。软件会有太多的偏差、抖动等。即使付出巨大的努力,它也远非好(更不用说完美)。
  • 脉宽调制en.wikipedia.org/wiki/Pulse-width_modulation我有基于ARM926EJ-S的CPU(NXPs ASC8848A),它没有HPET
  • @AaronDigulla:问题提到了 ARM 400MHz。 HPET 是特定于 x86 的(尽管新的 ARM 有类似的东西)。
  • 许多 ARm 设备都包含带 PWM 输出的硬件定时器,但 ASC8848A 是为视频编码应用而设计的。它目前缺少数据表或手册,但可用信息并不表明它具有硬件 PWM。

标签: c linux linux-kernel embedded pwm


【解决方案1】:

Pulse-width modulation 在软件中很难做到。理论上,您所要做的就是在您的 CPU 中找到一个具有足够分辨率的计时器,附加一个 IRQ 处理程序并启动它。

如果您查看时钟,您会觉得无法在 400 MHz CPU 上执行 10 kHz PWM 感觉很疯狂 - 每个脉冲您将有 400000/10 = 40000 个 CPU 周期,这肯定够了吗?

也许不是。 linux内核使用中断本身来进行内核调用。然后你有其他中断(DMANMIs,其他计时器,...)。根据定时器中断的优先级,其中一些可以阻止它。这意味着网络操作或其他事情可能会延迟您的 IRQ 处理程序。如果您使用 Linux 内核 API 来处理中断,那么您会遇到更多问题:内核不会调用您的处理程序。相反,真正的 IRQ 处理程序将收集有关中断的一些信息并将其作为任务附加到链中。

最终,内核将查看该链并处理其中的任务。

另一个问题是 CPU 也不会立即响应 IRQ。有些操作码是你不能打断的。

这会导致很多抖动。

如果您想尝试它,那么您应该在汇编程序中编写自己的 IRQ 处理程序,该处理程序会执行所有处理 - 获取 IRQ 并写入新的输出值。不要使用标准的 linux 中断 API。然后你必须禁用这个定时器的中断 API(或者内核可能会删除你的处理程序)。

您必须使用在 CPU 中具有非常非常高优先级的计时器 - 任何可能延迟它的事情都会毁了您的一天。

即使您有 40K 的 CPU 周期可以使用:总有其他软件也想咬一口。所以你可能无法运行其他任何东西。

【讨论】:

    【解决方案2】:

    “如果你想要一些精确的时序,请使用硬件 PWM。软件会有太多的偏差、抖动等。即使付出巨大的努力,它也远非好(更不用说完美)。”

    上述答案并不完全正确,尽管它显示了 PWM 的一些问题:

    问题是,无论输出信号是来自硬件 PWM 发生器还是来自软件控制的 GPIO,应用程序必须在单个 PWM 周期内执行所有计算。 否则,抖动将被观察为不正确的平均 PWM 值或不正确的平均信号相移。

    换句话说,使用硬件 PWM 的唯一好处是计算可以与 PWM 脉冲边沿异步完成,但它们必须与 PWM 周期的开始/结束同步。

    【讨论】:

      猜你喜欢
      • 2012-04-11
      • 2013-12-17
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 2016-03-25
      相关资源
      最近更新 更多