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

我在MX28(ARMv5)上运行linux,并使用GPIO线路与设备通信。 不幸的是,该设备有一些特殊的时间要求。 GPIO线上的低电平持续时间不能超过7us,高电平没有特殊的时序要求。 该代码作为内核设备驱动程序实现,并通过直接寄存器写入来切换GPIO,而不是通过内核GPIO API。 为了testing,我只产生3个脉冲。 这个过程如下,都在一个函数中,所以它应该适合在指令caching中:

  • 设置gpio高
  • 保存标志并禁用中断
  • gpio低
  • 暂停
  • gpio高
  • 再重复2次
  • 恢复标志/重新启用中断

这是连接到GPIO的逻辑分析仪的输出。

三个脉冲的图片

大部分时间它的工作很好,脉冲持续时间在1us以下。 然而,大约10%的低点持续了很多很多微秒。 即使中断被禁用,也会导致代码stream被中断。

奇怪的长脉

我很茫然。 RT Linux在这里可能没有什么帮助,因为问题不是延迟,它似乎是在低端发生的事情,尽pipe没有任何事情可以在IRQ禁用的情况下中断它。 任何build议将大大,非常感谢。

Solutions Collecting From Web of "ARM Linux内核驱动程序中的关键时序"

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

但是,您还有四个与Linux有关的其他问题。

  1. TLB未命中和页面走路。
  2. 数据中止。
  3. DMA大师偷。
  4. FIQ中断。

除非您拥有巨大的显示屏,否则LCD主机不太可能窃取足够的带宽。 你的显示器是否大于1 / 4VGA? 如果不是,这只是内存带宽的10%,这将与处理器一起传输。 你有以太网或USB活跃? 这些外设具有更高的数据速率,并可能导致与SDRAM的这种类型的争用。

所有这些问题都可以通过编写您的开关PC相关并将其复制到IRAM来避免。 请参阅: iram_alloc.c ; 这个文件应该可以移植到老版本的Linux上。 XBAR开关允许同时从SDRAM和IRAM提取数据。 IRAM仍然可以成为其他DMA主站的目标。 如果确实按下了,则将代码移到系统中没有其他主设备可以访问的ETB缓冲区。

TLB未命中实际上可能非常陡峭,因为它可能需要运行几个单跳 SDRAM周期; 仍然应该在1uS以下。 您没有发布代码,所以可能是因为某个变量和/或其他引起的数据错误不可屏蔽。

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

ETBIRAM都是32位数据路径和低等待状态。 或者比DDR-SDRAM的反应更好。

我们已经通过使用FIQIRAM使用位撞击以另一种协议在IMX258上切换GPIO来实现亚微秒响应。

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

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

您可以尝试通过对齐临界区域来避免临界区域内存控制器延迟,以避免跨越缓存行。 或者预取你将需要的代码。 但是,这将是非常不便携的,并为未来的维护创造一个噩梦。 仍然不保护从总线争用访问内存映射GPIO。