嵌入式Linux设备驱动程序:用户空间中的设备驱动程序
Embedded Linux
device drivers: Device drivers in user space
Interfacing with Device Drivers
Device drivers in user space
用户空间中的设备驱动程序
在开始编写设备驱动程序之前,请暂停片刻,考虑是否确实有必要。对于许多常见类型的设备,有通用的设备驱动程序,允许您直接从用户空间与硬件交互,而不必编写一行内核代码。用户空间代码当然更容易编写和调试。它也不包括在GPL中,尽管我觉得这本身并不是一个很好的理由来这样做。
这些驱动程序分为两大类:通过sysfs中的文件(包括GPIO和led)进行控制的驱动程序,以及通过设备节点(如I2C)公开通用接口的串行总线。
GPIO
通用输入/输出(GPIO)是最简单的数字接口形式,因为它可以直接访问各个硬件引脚,每个引脚可以处于两种状态之一:高或低。在大多数情况下,您可以将GPIO管脚配置为输入或输出。你甚至可以使用一组GPIO管脚,通过操作软件中的每个位来创建更高级的接口,比如I2C或SPI,这种技术被称为位碰撞。主要的限制是软件循环的速度和精度,以及您希望专用于它们的CPU周期数。一般来说,除非配置一个实时内核,否则很难达到比毫秒更好的计时器精度。GPIO更常见的用例是读取按钮和数字传感器以及控制led、电机和继电器。
大多数soc有很多GPIO位,这些位被组合在GPIO寄存器中,通常每个寄存器32位。片上GPIO位通过多路复用器(称为pinmux)路由到芯片封装上的GPIO管脚。在电源管理芯片和专用的GPIO扩展器中,可能有额外的GPIO引脚,通过I2C或SPI总线连接。所有这些多样性都由一个名为gpiolib的内核子系统来处理,它实际上不是一个库,而是GPIO驱动程序用来以一致的方式公开I/O的基础设施。在Documentation/gpio的内核源代码中有关于gpiolib实现的详细信息,驱动程序本身的代码在drivers/gpio中。
应用程序可以通过/sys/class/gpio目录中的文件与gpiolib交互。下面是一个典型的嵌入式板(BeagleBone Black)的示例:
ls /sys/class/gpio
export
gpiochip0 gpiochip32 gpiochip64 gpiochip96
unexport
名为gpiochip0到gpiochip96的目录代表四个GPIO寄存器,每个寄存器有32个GPIO位。如果您查看其中一个gpiochip目录,您将看到以下内容:
ls
/sys/class/gpio/gpiochip96
base
label ngpio power subsystem uevent
名为base的文件包含寄存器中第一个GPIO引脚的编号,ngpio包含寄存器中的位数。在本例中,gpio