背景:
我有一个PCI卡,它基本上是一个时钟。它通过GPS获取时间,并将当前时间保存在特定的寄存器中。
目标:
我想一遍又一遍地读取有限数量的寄存器/字节(例如当前时间),并使用尽可能低的延迟时间()。(时钟提供了非常高的精度,我认为我会放松精度,延迟时间越长。)操作系统是RedHat。程序设计语言为C/C++。我还想写到设备内存,这样延迟就不是问题了。
可能的办法:
我看到了这些方法。如果你看到另一个,请告诉我:
问题:
发布于 2018-07-14 16:00:29
方法3或4应能正常工作。它们之间在延迟方面没有区别。延迟时间约为100 ns。
如果您需要初始化设备,或者控制哪些应用程序可以访问它,或者一次强制执行一个读取器等,那么就需要方法4。方法3看起来有点麻烦,因为它跳过了所有这些。但如果你不需要这样的东西,那就更简单了。
字符设备的延迟肯定更高,因为每次读取该设备时,它都需要内核转换。
DMA方法的延迟完全取决于设备将时间写入内存的频率。CPU访问内存的延迟比MMIO低,但是如果设备每毫秒只执行DMA一次,那么这就是您的延迟。此外,该方法生成大量无用的DMA通信量,因为CPU读取值的频率远远低于写入的频率。
发布于 2018-07-16 20:21:30
加上@prl的答案..。
方法3在我看来是完全合法的。这就是它的目的。您可能想看看内核文档文件:https://www.kernel.org/doc/Documentation/filesystems/sysfs-pci.txt
您还可以使用/sys文件系统来查找设备。首先,请注意时钟卡的供应商ID和设备ID (以及子系统供应商/设备(如果需要),然后您可以轻松地遍历/sys/devices层次结构,查找匹配的设备(使用vendor、device等特殊文件)。一旦您找到它,您大概知道要从设备的数据表中打开哪个resourceN文件,然后在适当的偏移量处打开它,您就完成了。
这一切都假定您的设备已经配置和启用。通常,当系统启动时,不启用PCI设备来执行任何操作。有些驱动程序需要声明设备,并对其进行初始化/配置。一旦完成,如果只通过读取一两个寄存器就可以访问时间,您可以使用方法3 (我不确定: PCI设备可能是自初始化的,但我从未见过)。我认为至少需要一些东西来启用它的内存空间。如果设置足够小/足够简单,很可能可以从用户空间完成。)
与方法4的主要区别在于,控制设备的驱动程序将提供对允许区域被显式mmapd的支持。对于用户空间应用程序,除了所使用的设备名称之外,这两种方法之间没有什么差别。对于方法4,驱动程序可能会提供一个符号设备名称/dev/clock0或类似于用户空间应用程序使用的设备名称(并且假定应用程序不需要找到设备,它只知道打开设备文件名)。
在用户空间中,您将以与任何一种方法几乎相同的方式执行mmap操作。在方法4中,驱动程序内部提供映射的物理地址--可能还有偏移--而不是一般的PCI子系统,但不管是哪种方式,它都只是open + mmap。
Linux驱动程序编程并不是非常困难,但是如果您以前没有这样做,就会有一个很大的学习曲线,所以除非确实需要这样做,否则我肯定不会使用方法4。
https://stackoverflow.com/questions/51337083
复制相似问题