我打算为一些内存映射硬件编写一个linux驱动程序(它在一个FPGA中,所以如果需要我可以在两端调整这个内存映射接口)。
该 FPGA 逻辑生成一系列数据报,我必须对其进行处理,然后通过以太网链路进行传输。处理或网络代码都没有理由在内核中,所以我询问将数据块从硬件移动到用户空间的“最佳”机制。最大的复杂性是用户空间处理应该分布在多个进程之间。
数据速率不是很高(高达 1Mbps),mmio 接口由一个相当深的 FIFO(目前 2KB,可以增加到 8KB)提供,所以我认为高优先级的用户模式进程可以跟上。
我真正想要的是一个指向具有现有多播用户空间接口的现有驱动程序的指针(并且并不复杂)。但是,必须做的事情的大纲将是一个合理的替代品。
到目前为止,我收集了以下想法:
AF_NETLINK:支持多播,为我负责缓冲。但是API不稳定,我必须定义一个新的socket id,这可能与其他in-tree驱动程序冲突,而且用户模式接口非常专业,我不能使用标准工具
socat
来测试数据流。从用户空间传递一个数据报模式套接字或 FIFO 文件描述符,并写入它(如何?)。有一个我可以应用的 unix 域数据报套接字多播补丁。
将字符模式设备暴露给单个高优先级用户模式应用程序,该应用程序充当 unix 域数据报套接字服务器并将数据报复制到每个连接的节点。是否为字符模式设备保留了数据报边界(即,如果我的驱动程序
read
函数返回的字节数少于fread
缓冲区大小,将把fread
该数据块作为一个单元返回,或者它可以分段和重新组装块吗?如果我使用read (2)
而不是它有帮助fread (3)
吗?是否有类似EMSGSIZE
的驱动程序的读取函数可以用来指示数据报被截断,或者仅适用于套接字?)暴露一个可以被多个用户模式应用程序同时打开的字符模式设备,并将数据缓冲到每个内核中。
我倾向于使用具有重新路由传入数据包的 unix 域服务器的字符模式设备。这使我不必在内核驱动程序中实现缓冲逻辑。那么问题就变成了如何在select
中断发生时从调用或阻塞读取中唤醒用户进程。如果数据已经可用,我的函数似乎poll
可以读取控制寄存器并返回,如果没有,则取消屏蔽中断。POLLIN|POLLRDNORM
然后中断处理程序将使用wake_up
标记wait_queue
为准备就绪。 read
总是会屏蔽中断。