简体   繁体   English

Linux内核设备驱动程序需要访问用户空间中的共享对象

[英]Linux Kernel device driver needs access to shared object in userspace

I am trying to write a network device driver for Linux. 我正在尝试为Linux编写网络设备驱动程序。 The device that I have has an API available that allows me to access all of the features I need through a shared object that exists in userspace. 我所拥有的设备有一个可用的API,允许我通过用户空间中存在的共享对象访问我需要的所有功能。

I want to write a network driver such that I can make the device show up as a CAN interface. 我想编写一个网络驱动程序,以便我可以将设备显示为CAN接口。 However, in order to interact with the device I need to use a specific shared object that exists in userspace. 但是,为了与设备交互,我需要使用存在于用户空间中的特定共享对象。

The reason that I need a network device driver is to expose a CAN Interface that can be interacted with via the SocketCAN utilities. 我需要网络设备驱动程序的原因是暴露可以通过SocketCAN实用程序与之交互的CAN接口。

Is there a way that I can write a network device driver in userspace? 有没有办法在用户空间编写网络设备驱动程序? Or what would the best way for me to architect a solution? 或者,构建解决方案的最佳方式是什么?

Tl;Dr TL;博士

Need to write a device driver for a device which can only be interacted with from userspace via a supplied shared object which exposes the API. 需要为设备编写设备驱动程序,该驱动程序只能通过提供的公开API的共享对象与用户空间进行交互。 I need the device to show up as a network interface in order to utilize the SocketCAN utilities and other applications that communicate with CAN interfaces in Linux. 我需要将设备显示为网络接口,以便利用SocketCAN实用程序和其他与Linux中的CAN接口通信的应用程序。

What are my options here? 我有什么选择? What can I do? 我能做什么?

Thanks! 谢谢!

So you are saying that there is no driver for your network device in kernel at all, and it can be only accessed via some user-space library? 所以你说根本没有内核中的网络设备驱动程序,它只能通过一些用户空间库访问? In that case shared library you mentioned should be communicating with your network device by memory mapping your /dev/mem file, in order to be able to read/write to hardware registers. 在这种情况下,您提到的共享库应该通过内存映射 / dev / mem文件与您的网络设备进行通信,以便能够读/写硬件寄存器。 Or perhaps by using some UIO . 或者也许通过使用一些UIO

So your driver should be also developed in user-space then... Then the actual question you should ask is how to use kernel CAN API from user-space? 所以你的驱动程序也应该在用户空间开发然后......那么你应该问的实际问题是如何从用户空间使用内核CAN API? And is it possible at all in the first place? 首先它是否可能? For answers I guess you should look at Documentation/networking/can.txt . 对于答案我想你应该看一下Documentation / networking / can.txt And if the answer is "no" (means you can't expose CAN interface from user-space), then you should develop also some kernel driver which would interact with your user-space part, exposing CAN interface. 如果答案是“否”(意味着你不能从用户空间公开CAN接口),那么你应该开发一些内核驱动程序,它将与你的用户空间部分交互,暴露出CAN接口。

In ideal world the whole driver architecture would look like this: 在理想世界中,整个驱动程序架构如下所示:

理想的驱动架构

But you need to use some ( proprietary , if I understand correctly) shared library API to interact with your device. 但是你需要使用一些( 专有的 ,如果我理解正确的话)共享库API来与你的设备进行交互。 So I propose you to use next driver architecture, which depicted on the image below: 所以我建议你使用下一个驱动程序架构,如下图所示:

  • blue color stands for parts that need to be developed 蓝色代表需要开发的部件
  • magenta is for already existing code 洋红色是已有的代码

建议的驱动程序架构

In a nutshell, your app and driver both make a shim between SocketCAN API and shared library API. 简而言之,您的应用和驱动程序都在SocketCAN API和共享库API之间形成了一个垫片

So you need to develop 2 components: 所以你需要开发2个组件:

  1. Driver (on kernel side). 驱动程序(在内核端)。 It's in charge of: 它负责:
    • talking to SocketCAN utilities SocketCAN实用程序交谈
    • talking to your user-space application 与您的用户空间应用程序交谈
  2. Application (in user-space); 应用(在用户空间); it's probably should be a daemon , as it's gonna be running constantly. 它可能应该是一个守护进程 ,因为它会不断运行。 It's in charge of: 它负责:
    • talking to shared library 与共享图书馆交谈
    • talking to your driver 跟你的司机说话

The last question remains is which kernel API to use to interact between your kernel space driver and user-space application (marked as IPC on picture). 最后一个问题是用于在内核空间驱动程序和用户空间应用程序之间进行交互的内核API(在图片上标记为IPC )。 It strictly depends on which kind of data you are going to send between two, and how much of data you will want to send, and which way of sending is most appropriate for your task. 它严格依赖于您要在两者之间发送哪种数据,以及您希望发送多少数据,以及哪种发送方式最适合您的任务。 It may also depend on your shared library API: you probably don't want to spend much of CPU time to convert messages format (as you already have triple context switching with this driver architecture, which is not really nice for performance). 它也可能取决于您的共享库API:您可能不希望花费大量的CPU时间来转换消息格式(因为您已经使用此驱动程序体系结构进行了三重 上下文切换 ,这对性能来说并不是很好)。 So it's probably should be something packet-oriented, like Netlink . 所以它可能应该是面向数据包的东西,比如Netlink

Next reading can be useful to figure out which IPC to use: 下一步阅读可以用来确定使用哪个IPC:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM