将数据从内核驱动程序复制到用户空间驱动程序的最佳方法

时间:2017-04-04 13:37:58

标签: linux linux-kernel linux-device-driver

我正在使用当前从传感器读取数据的内核驱动程序。 现在我必须编写一个用户空间应用程序,它将调用内核的sensor_read() API并将数据发送到云。

如何向用户空间公开内核的sensor_read()调用并从用户空间读取此数据?数据大约是10个字节。

3 个答案:

答案 0 :(得分:3)

  

如何向用户空间公开内核的sensor_read()调用并从用户空间读取此数据?

最有可能你应该使用IIO内核框架,因为它专门用于编写传感器驱动程序。 IIO为您的驱动程序公开必要的文件(/sys/bus/iio//dev/iio*)。您可以read()这些文件,或poll()个(处理中断)。

官方文件可用here。您也可以使用一些现有的驱动程序作为参考,请查看此处:drivers/iio/

在引入IIO框架之前,通常会手动为驱动程序提供sysfs文件。因此,如果你使用足够老的内核,那应该是编写驱动程序的方法:手动处理你的总线(如I2C)和sysfs文件。但是,最好的方法是使用新的内核和IIO。

  

我正在研究Gyro + accel传感器。 Linux驱动程序将为它们两者发送EV_MSC类型的事件

芯片上有多个传感器并不罕见。在这种情况下,您应该创建两个不同的驱动程序:一个用于加速计,一个用于陀螺仪。这样,您将拥有两个不同的文件,每个传感器一个文件。

例如,看看它是如何为LSM330DLC芯片(加速度计+陀螺仪)做的:

两个驱动程序都从驱动程序的探测函数调用iio_device_register()函数,该函数创建相应的文件(您可以读取/轮询)。有关详细信息,请参阅documentation

  

根据我的理解,我将从用户空间打开两个输入设备,然后添加到我们要轮询的FD列表中。所以当有新事件时,我怎么能确定这个事件是来自Gyro还是aceel?

如果您对如何处理用户空间中的两个/dev/input/event*文件感到好奇,那么您基本上有两种选择:

  • 使用阻止I / O:您可以在不同的线程中读取/轮询它们
  • 使用非阻塞I / O:您可以在同一个线程中将这些文件作为O_NONBLOCK打开,只打read()个;如果新数据尚不可用 - 它将返回-1,errno将设置为EAGAIN;你可以在无限循环中进行读取,例如

This回答包含如何在C中处理输入文件的示例。here您可以阅读有关阻塞/非阻塞I / O的信息。

答案 1 :(得分:1)

您可以使用IOCTL(ioctl / read)调用从用户空间访问内核函数。

请参阅以下链接以获取样本: http://www.tldp.org/LDP/lkmpg/2.4/html/x856.html

答案 2 :(得分:1)

有许多方法可以从内核空间访问传感器数据到用户空间

  1. 检查您使用的传感器的相关驱动程序。检查它是否支持/提供sysfs支持。
  2. 您可以从/sys/class/接口读取数据。您需要确保将相关参数导出到sysfs。 例如:温度传感器应在sysfs条目中具有导出的温度值(等效因子)。

    示例(以下示例仅为小说)

    cat /sys/class/hwmon/tempsensor/value

    cat /sys/class/hwmon/tempsensor/min_value

    cat /sys/class/hwmon/tempsensor/max_value

  3. 在某些驱动程序中,您可以通过ioctl / read / write api来读取它们以读取/写入传感器数据。