首页 > 解决方案 > 以低延迟访问 PCI 内存条 (Linux)

问题描述

背景:

我有一个 PCI 卡,它基本上是一个时钟。它通过 GPS 获取时间并将当前时间保存在某个寄存器中。

目标:

我想以尽可能低的延迟一次又一次地读取有限数量的寄存器/字节(例如当前时间)。(时钟提供了非常高的精度,我认为延迟越高,精度就越低。)。操作系统是红帽。编程语言是 C/C++。我还想写入设备内存,因此延迟不是问题。

可能的途径:

我看到了这些方式。如果你看到另一个,请告诉我:

  1. 编写 Linux 内核模块驱动程序,该驱动程序创建一个字符设备(或每个寄存器读取一个字符设备)。然后用户空间应用程序可以对 /dev/ 文件进行“读取”。
  2. DMA
  3. 通过用户空间应用程序(系统调用)将 sysfs resourceX 文件映射到用户空间。(例如这里
  4. 编写实现 mmap 文件操作的 Linux 内核模块驱动程序。

问题:

  1. 在实际读取寄存器时,哪种方式延迟最低?我知道 mmap 在内核中会导致很多开销,但据我所知,这仅用于初始化。
  2. 方式3是合法的方式吗?对我来说,这看起来像是一个黑客。如何从应用程序中自动确定 /sys/ 路径?
  3. 方式3和4有区别吗?我是 PCI 驱动程序编程的新手,我想我并不真正了解 4 的工作方式。我读过这个(和那本书的其他章节),但也许你可以给我一个提示或一个例子。我会很感激的。

标签: linuxmemorylinux-device-drivermmappci

解决方案


方法 3 或 4 应该可以正常工作。它们之间在延迟方面没有区别。延迟大约为 100 ns。

如果您需要初始化设备,或者控制允许哪些应用程序访问它,或者一次强制一个阅读器等,则需要方法 4。方法 3 看起来有点像黑客,因为它跳过了所有这些。但如果你不需要这些东西,它会更简单。

字符设备的延迟肯定更高,因为每次读取设备时都需要内核转换。

DMA 方法的延迟完全取决于设备将时间写入内存的频率。CPU 访问内存的延迟比 MMIO 低,但如果设备每毫秒只执行一次 DMA,那么这就是您的延迟。此外,该方法会产生大量无用的 DMA 流量,因为 CPU 读取值的频率远低于写入值。


推荐阅读