嵌入式Linux应用开发中,系统经常会通过GPIO接入按键、各种感应开关等传感器,或控制电源开关、继电器等设备。
要在Linux应用层控制GPIO有两种方式:
为了用户空间运行的应用程序能够使用GPIO,Linux内核通过sysfs导出了与GPIO控制相关的文件,在/sys/class/gpio
目录下,根据芯片不同,其下又有多个芯片子目录gpiochipN
,例如在我使用的旭日X3pi中,有一个子目录gpiochip0
,如果有多个带有GPIO的芯片,会有多个子目录。每个子目录中主要有以下与这个芯片相关的信息文件:
/sys/class/gpio
目录下有两个文件export
和unexport
,用来导出和取消导出GPIO,向export
文件中写入要导出的GPIO的编号,会导出相应的GPIO,导出后会在/sys/class/gpio
目录下生成一个与GPIO对应的子目录。向unexport
文件写入GPIO编号会取消导出相应的GPIO。例如在X3pi上导出GPIO3:
root@ubuntu:/sys/class/gpio# ls
export gpiochip0 unexport
root@ubuntu:/sys/class/gpio# echo 3 >export
root@ubuntu:/sys/class/gpio# ls
export gpio3 gpiochip0 unexport
root@ubuntu:/sys/class/gpio#
这个GPIO编号是全局GPIO编号,是在芯片的GPIO编号基础上加上芯片对应的base值。这里芯片的GPIO编号是3,芯片对应的base值是0,所以全局GPIO号还是3。
不同芯片的GPIO编号如何计算需要参考芯片相应文档,例如有的芯片GPIO名是A3,B5这样,其中A0-AF编号为0~15,B0-BF编号为16~31。
GPIO导出后,会生成一个名为gpioN
的目录,其中N为GPIO编号,目录下有一些文件用来控制该GPIO或读取该GPIO的状态,主要有:
使用流程:
要通过API控制GPIO,首先要知道GPIO芯片对应的设备节点,例如,在旭日X3pi上,GPIO 芯片对应的设备节点是/dev/gpiochip0
,知道设备节点后,可以通过open
打开设备节点,然后通过fcntl
来控制GPIO,GPIO 控制相关的控制命令和数据结构定义在/usr/include/linux/gpio.h
文件中,注意这不是kernel头文件。通过芯片对象可以进一步获取引脚(就是代码中的line或者这里说的GPIO)的控制对象,从而控制引脚。
由于整个过程比较复杂,这里不具体介绍了,因为已经有人写了一个库来通过API控制GPIO,这个库就是libgpiod。
注意:使用libgpiod
时,如果内核版本低于5.5,要使用v1.4以下版本,但内核版本至少在4.8以上。v0.3以上版本的测试程序需要内核版本在v4.11以上,v0.3.2以上版本的测试程序需要内核版本在v4.12.6以上,v1.1以上版本的测试程序需要内核版本在4.16以上,v1.4以上版本的测试程序需要内核版本在5.1以上。