使用附加参数在 Linux 驱动程序中写入数据
我对驱动程序开发不太熟悉,但我必须执行简单的驱动程序适配,并且我不确定要走的路。我不是在寻找详细的解释(我可以在书中查看),而是更多地了解向我展示知识收集起点的“最佳实践”。
问题如下:
最初,我们有一个非常简单的字符驱动程序来执行此操作:
User "write" driver copies
Space ==== packets =====> the data
Code to open fd from user space
of the driver and passes it to
a hw controller
要执行的简单调整是,现在硬件控制器需要一个附加的数字标记来识别数据包的类型。通常,该标签应与每个写入的数据包一起指定。
什么是更明智的做法?
- 创建一个单独的 ioctl 调用来提供此标记,然后执行真实数据包数据的“write”调用(然后在用户空间中使用“ioctl”和“write”)。
- 创建一个 ioctl 调用以同时传递标记和数据包数据(然后在用户空间中使用此“ioctl”调用)
- 创建一个附加结构(在用户空间和驱动程序之间共享),其中包含标记和指向缓冲区的指针,以及然后在用户空间中“写入”该结构(因此,从用户空间复制两次:一次用于结构,第二次用于数据包数据)。
- ...?
任何提示/评论/建议都非常受欢迎。
I am not really familiar with driver development, but I have to perform a simple driver adaptation and I am not sure about the way to go. I am not looking for detailed explanations (that I can check up in a book), but more about what are the "best practices" that show me the starting point of my knowledge gathering.
The problem is the following:
Initially, we had a very simple char driver performing this operation:
User "write" driver copies
Space ==== packets =====> the data
Code to open fd from user space
of the driver and passes it to
a hw controller
The simple adaptation to perform is that, now, the hw controller needs an additional numeric tag to identify the type of packet. Normally, this tag should be specified together with every written packet.
What is more sensible to do?
- create a separated ioctl call to provide this tag, and then perform the "write" call of the real packet data (and then use "ioctl" and "write" in user space).
- create an ioctl call to pass simultaneously the tag and the packet data (and then use this "ioctl" call in user space)
- create an additional structure (shared between user space and driver), containing the tag and the pointer to the buffer, and then "write" this structure in user space (thus, copying twice from user space: one for the struct and a second one for the packet data).
- ...?
Any hint/comment/suggestion is more than welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一个和第三个选项实际上在性能方面是相同的(两次调用内核并返回),但使用 write 比 ioctl 更漂亮。
第二个选项为您节省了进入内核并返回的上下文切换,但很丑陋。
我将定义一个具有数据包类型的第一个字节的结构,并用数据包数据保留一个缓冲区,但将使用 writev() 而不是 write() 将其发送到内核。
它不仅节省了额外的上下文切换,实际上还允许您在一次调用内核中发送多个数据包(及其类型)(如果可用)。
有人会说我的建议和你的第二个建议没有区别。也许他们是对的:-)
The first and third options are practicably the same performance wise (two calls into kernel and back) but using write is prettier then ioctl.
The second option save you a context switch into the kernel and back, but is ugly.
I would define a structure with a first byte of packet type and rest a buffer with packet data but will user writev() rather then write() to send it to the kernel.
Not only does it saves you the extra context switch, it actually allows you to send several packets (and their types) in a single call to kernel, if available.
Some would say there is no difference between my suggestion and your second one. Perhaps they are right :-)