我们试图为一个自定义数据采集设备编写一个驱动程序/API,它捕获了几个“通道”的数据。为了便于讨论,让我们假设这是一个多通道的视频捕获设备。该设备通过8xPCIe Gen-1链路连接到系统,理论吞吐量为16 16Gbps。我们的实际数据速率将在2.8Gbps (~350 be /秒)左右。
由于数据速率需求,我们认为我们必须小心驱动程序/API体系结构。我们已经实现了基于描述符的DMA机制和相关的驱动程序。例如,我们可以从设备中启动256 it的DMA事务,并成功完成。然而,在这个实现中,我们只捕获内核驱动程序中的数据,然后删除它,我们根本没有将数据流到用户空间。本质上,这只是一个小的DMA测试实现。
我们认为我们必须将问题分为三个部分: 1.内核驱动程序2.用户空间API 3.用户代码
获取设备在PCIe地址空间中具有寄存器,该寄存器指示是否有从该设备读取的任何信道的数据。因此,我们的内核驱动程序必须轮询这个位向量。当内核驱动程序看到这个位集时,它会启动一个DMA事务。然而,用户应用程序不需要知道所有这些DMA事务和数据,直到整个数据块准备就绪(例如,假设设备为我们提供了每个事务的16行视频数据,但我们只需要在整个视频帧准备就绪时才通知用户)。我们只需要将整个帧传输到用户应用程序。
这是我们的第一次尝试:
以上所有内容都正常工作,只是性能很差。我们只能达到2MB/秒的传输速率。我们需要完全重写这一点,我们对任何建议或例子的指针都是开放的。
其他说明:
发布于 2016-03-15 20:13:43
你现在可能已经过去了,但如果不是的话,这是我的2p。
您需要编写一个阻塞读,为其提供一个大内存缓冲区。驱动程序读取op (a)获取用户缓冲区的用户页列表,并将它们锁定在内存(get_user_pages)中;(b)使用pci_map_sg创建分散列表;(c)遍历列表(for_each_sg);(d)为每个条目写入相应的物理总线地址和数据长度,作为我假定的“描述符”。
该卡现在有一个描述符列表,这些描述符对应于大型用户缓冲区的物理总线地址。当数据到达卡时,它直接将其写入用户空间,写入用户缓冲区,而用户级读取仍被阻塞。当它完成描述符列表时,卡片必须能够中断,否则就没用了。驱动程序响应中断,并解除对用户级读取的阻塞。
就是这样。当然,细节是令人讨厌的,而且文档也不完整,但这应该是基本的架构。如果您真的没有中断,您可以在内核中设置一个计时器来投票以完成传输,但是如果它真的是一张自定义卡,您应该拿回您的钱。
https://stackoverflow.com/questions/31876296
复制相似问题