【发布时间】:2013-06-15 08:28:17
【问题描述】:
我在 MX28 (ARMv5) 上运行 linux,并使用 GPIO 线与设备通信。不幸的是,该设备有一些特殊的时序要求。 GPIO 线上的低电平不能持续超过 7us,高电平没有特殊的时序要求。该代码作为内核设备驱动程序实现,并通过直接寄存器写入而不是通过内核 GPIO api 来切换 GPIO。为了测试,我只产生 3 个脉冲。流程如下,全在一个函数中,所以它应该适合指令缓存:
- 将 gpio 设置为高
- 保存标志并禁用中断
- gpio 低
- 暂停
- gpio 高
- 再重复 2 次li>
- 恢复标志/重新启用中断
这是连接到 GPIO 的逻辑分析仪的输出。
大多数情况下,它的效果都很好,脉冲持续时间不到 1us。然而,大约 10% 的低点会持续很多很多微秒。即使中断被禁用,某些东西也会导致代码流被中断。
我很茫然。 RT Linux 在这里可能无济于事,因为问题不在于延迟,它似乎是在低电平期间发生的事情,即使在禁用 IRQ 时没有任何东西可以中断它。任何建议将不胜感激。
【问题讨论】:
-
是否有一些额外的核心或功能单元(DMA 等)可以占用总线?如果系统运行诸如 uboot 之类的东西,您是否可以尝试将代码构建到其中作为比较测试,或者在内核启动的早期在初始化之前在纯汇编中执行它?
-
我不这么认为。 GPIO 是专用的。这看起来像 cpu 停止执行代码一段时间。我怀疑正在发生的是页面错误或类似的事情。我尝试在它的开头添加一个障碍,以防万一出现乱序执行的问题,但它没有改变任何东西。 U-Boot 充当引导加载程序,而我现在执行的大部分代码已经是汇编程序,所以我可能可以在 u-boot 中添加一个命令来执行此操作。
-
@Arcane:如果您在禁用中断的情况下出现页面错误,那么事情不会暂停——它们会中断。太可怕了。 Chris 正在讨论的内容(主内存总线上的多个总线主控器)将导致内核暂停执行(在 fetch-decode-execute 的“fetch”阶段),直到其他总线事务完成。例如,显示控制器通常具有优先权,因为从帧缓冲区中延迟读取会导致显示损坏。
-
智能使用指令缓存可能会避免通过主内存总线加载代码。
-
它甚至可能不是与另一个总线主机的竞争,它可能只是缓存未命中。您的 DRAM 使用什么时钟速度和 CAS 延迟?
标签: linux linux-kernel kernel arm driver