C 在内核空间与用户空间中工作

C 在内核空间与用户空间中工作,c,linux,linux-kernel,linux-device-driver,embedded-linux,C,Linux,Linux Kernel,Linux Device Driver,Embedded Linux,在我的项目中,我必须不断地从固件FIFO中读取大量数据。我一次读一个单词,在读了115个单词之后,所有的单词都被解析成一个结构。我有两种方法可以做到这一点: 1.)实现驱动程序,使其一次返回1个字,并在用户空间中进行所有打包 2.)通过IOCTL将结构传递给驱动程序,驱动程序执行115次读取,然后返回填充的结构 第2条对我很有吸引力,因为它可以让用户空间代码更干净,但我不确定是否能在驱动程序中完成所有这些工作。从标准实践和性能的角度来看,哪种方法更好 我认为这取决于驱动程序是否特定于硬件。如果希

在我的项目中,我必须不断地从固件FIFO中读取大量数据。我一次读一个单词,在读了115个单词之后,所有的单词都被解析成一个结构。我有两种方法可以做到这一点:

1.)实现驱动程序,使其一次返回1个字,并在用户空间中进行所有打包

2.)通过IOCTL将结构传递给驱动程序,驱动程序执行115次读取,然后返回填充的结构


第2条对我很有吸引力,因为它可以让用户空间代码更干净,但我不确定是否能在驱动程序中完成所有这些工作。从标准实践和性能的角度来看,哪种方法更好

我认为这取决于驱动程序是否特定于硬件。如果希望驱动程序理解设备的协议(它是特定于设备的驱动程序,而不是一般的驱动程序),那么#2可能是最好的选择,因为它可以最大限度地减少用户空间程序和内核之间的通信量。如果驱动程序应该合理地与硬件无关,那么#1就是您应该实现的(例如,如果它是通信协议的驱动程序,比如SPI/I2C,而不是设备的驱动程序)


就性能而言,#2几乎肯定更好,因为它需要1次系统调用而不是115次系统调用。

一种减少用户到内核空间通信的方法,同时保持用户空间的复杂性,就是让用户空间在一次调用中同时请求所有230字节的数据

然后在用户空间中执行位和字节操作

根据操作的工作方式,它甚至可以“就地”完成。您传递
struct
,将其填充,然后调用
prepare\u data
,这将完成所有的位修改。再进行一步,您可以将其隐藏在库函数后面,甚至
inline
头文件函数后面


现在内核空间只提供请求的字节,用户空间包含所有非平凡逻辑。这使得fencepost错误使您的计算机停机的可能性降低。

如果您的硬件允许,并且对获取这些数据的速度没有硬性的实时要求,下面是一种支持惰性的方法::-)

将固件的IO地址映射到用户空间。然后从你的用户空间程序中读取它


这适用于“固件”每秒仅生成1个数据的情况。

我假设在2中,只有当FIFO至少有115个字时,您才会调用驱动程序,如果没有,它会立即返回错误?这种“解析”非常重要,或者只是从
memcpy
中删除了一步?是的,驱动程序将检查是否有115个单词可用,如果没有,则返回。解析将是大量的按位添加和移位之类的操作。没有浮点运算或任何东西。顺便问一下:它总是115个字吗?允许用户空间说出应该读取多少,这是否值得呢?(目前可能验证这是预期的数字…)3。选项是在一次调用中将115个单词传递回内核,然后在用户空间中进行解析。不是一般的。谢谢你的建议。