ARM Linux内核驱动程序中的关键时序

时间:2013-06-14 18:31:01

标签: linux linux-kernel kernel arm driver

我在MX28(ARMv5)上运行linux,并使用GPIO线与设备通信。不幸的是,该器件有一些特殊的时序要求。 GPIO线路上的低电平不能超过7us,高电平没有特殊的时序要求。代码实现为内核设备驱动程序,并通过直接寄存器写入切换GPIO,而不是通过内核GPIO api。为了测试,我只生成3个脉冲。该过程如下所示,所有功能都集中在指令缓存中:

  • 设置gpio high
  • Save Flags&禁用中断
  • gpio low
  • 暂停
  • gpio high
  • 再重复2次
  • 恢复标志/重新启用中断

这是与GPIO相连的逻辑分析仪的输出。

Picture of three pulses

大部分时间它都很好用,脉冲持续不到1us。然而,大约10%的低点持续很多很多微秒。即使禁用了中断,也会导致代码流中断。

Weird long pulse

我不知所措。 RT Linux可能在这里没有帮助,因为问题不是延迟,它似乎是在低端发生的事情,即使没有任何东西应该在禁用IRQ时中断它。非常感谢任何建议。

2 个答案:

答案 0 :(得分:6)

IMX25(ARM926)上的ARM 缓存是16K代码,16K数据L1,长度为32byte或8条指令。 DDR-SDRAM控制器运行在133Mhz和16位总线,传输速率约为300MB / s。缓存填充应该只需要大约100nS,而不是9uS;这大约是100倍。

但是,Linux还有其他四个问题。

  1. TLB未命中并且页面表走了。
  2. 数据中止。
  3. DMA主人偷窃。
  4. FIQ中断。
  5. 除非你有一个巨大的显示器,否则LCD主机不太可能窃取足够的带宽。您的显示器是否大于1 / 4VGA?如果没有,这只是内存带宽的10%,这将与处理器一起流水线。你有以太网或USB有效吗?这些外设具有更高的数据速率,可能会导致与SDRAM的这种争用。

    通过编写相关的toggler PC并将其复制到IRAM,可以避免所有这些问题。见:iram_alloc.c;此文件应该可以移植到旧版本的Linux。 XBAR开关允许同时从SDRAM和IRAM提取。 IRAM 仍然可以成为其他 DMA 主服务器的目标。如果您真的被按下,请将代码移动到 ETB 缓冲区,系统中没有其他主机可以访问这些缓冲区。

    TLB未命中实际上可能非常陡峭,因为它可能需要运行多个单拍 SDRAM周期;仍然应该在1uS以下。您尚未发布代码,因此变量和/或其他可能导致数据错误无法屏蔽。

    如果您有任何使用 FIQ 的驱动程序,即使您屏蔽了正常的 IRQ 中断,它们仍可能仍在运行。例如,此系统的 ALSA 驱动程序通常使用 FIQ

    ETB IRAM 都是32位数据路径和低等待状态。任何一个都可能比DDR-SDRAM提供更好的响应。

    我们通过使用 FIQ IRAM 来实现子微秒响应,使用位冲击将IMX258上的GPIO切换为另一种协议。

答案 1 :(得分:3)

Chris提到的问题的一个可能的解决方法(除了内核模块代码的分页问题)是使用PWM外设,其中脉冲的持续时间被预编程并且时序在硬件中实现。

带有缓存的花哨处理器不适合硬实时工作。如果高速缓存未命中是非确定性的(并且高速缓存未命中完全确定性的设计并不足以证明花哨的处理器的合理性),则执行时间会有所不同。

您可以尝试通过对齐关键部分来避免关键部分中的内存控制器延迟,以便它不会跨越缓存行。或者预取您需要的代码。但这将是非常不便携的,并为将来的维护造成噩梦。并且仍然不能保护对内存映射GPIO的访问不受总线争用的影响。