9

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

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

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

三个脉冲的图片

大多数情况下它工作得很好,脉冲持续时间不到 1us。然而,大约 10% 的低点会持续很多很多微秒。即使中断被禁用,某些东西也会导致代码流被中断。

奇怪的长脉冲

我很茫然。RT Linux 在这里可能无济于事,因为问题不在于延迟,它似乎是在低电平期间发生的事情,即使在禁用 IRQ 时没有任何东西可以中断它。任何建议将不胜感激。

4

2 回答 2

6

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 上使用另一种协议使用 bit banging 切换 GPIO,实现了亚微秒级响应。

于 2013-06-14T21:24:26.103 回答
3

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

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

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

于 2013-06-14T18:47:12.757 回答