如何在Linux中以编程方式使用GPIO扩展器驱动程序?



我正试图配置我的Yocto Linux发行版来设置两个板上I2C GPIO扩展器,并记录如何以编程方式访问它们(即从C用户应用程序)。GPIO扩展器均为NXP PCA9557, GPIO -pca953x.c内核驱动支持。

我知道如何将这个驱动程序编译成内核(使用CONFIG_GPIO_PCA953X配置选项)并加载它(使用modprobe)。我也明白我可以在设备树中实例化这两个I2C设备(这是一个嵌入式设备,因此GPIO扩展器是静态和不变的):

gpio@20 {
compatible = "nxp,pca9557";
reg = <0x1a>;
gpio-controller;
#gpio-cells = <2>;
};

我缺乏的信息是如何使用gpio-pca953x驱动程序与这些实例化的设备?我需要将这些设备与特定的驱动程序关联吗?在用C编写的用户应用程序中,我使用什么api来访问它们?一旦我正确配置它们,它们是否就像普通的gpio一样?

我非常乐意阅读有关如何做到这一点的任何相关文档,无论冗长与否。我只是一个Linux设备驱动程序的初学者,不知道从哪里开始,尽管谷歌了很多。

正常工作时,驱动应在/dev中提供一个gpiochipX器件。这可以用于ioctl调用。

libgpiod库为与这些设备交互提供了一个友好的API。

在Yocto中安装libgpiod包。它附带了一些方便的命令行工具用于调试。

  • gpiodetect -列出系统中存在的所有gpiochip,它们的名称,标签和GPIO线数

  • gpioinfo -列出指定gpiochip的所有行,它们的名称,消费者,方向、活动状态和附加标志

  • gpioget -读取指定GPIO线的值

  • gpioset -设置指定GPIO线路的值,可能保留线路导出并等待超时,用户输入或信号

  • gpiofind -查找给定行名的gpiochip名称和行偏移

  • gpiomon -等待GPIO上的事件,指定要观察的事件。在退出事件之前要处理多少事件应该报告到控制台


如果你没有这个文件,那么驱动程序没有启动。查看dmesg是否有线索。

# dmesg | grep pca953x
[    0.208762] pca953x 1-0020: using AI

您还可以检查pca芯片是否可以在i2c上访问。列出i2c总线并找出pca9557在哪个总线上。

# i2cdetect -l
i2c-0   21a0000.i2c
i2c-1   21a4000.i2c
i2c-2   21a8000.i2c

假设pca芯片在i2c-1总线上。检测总线上的设备

# i2cdetect -y 1
0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:       -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

表中应该包含

  • UU在1a地址如果pca953x驱动正在运行,
  • 1a在1a地址,如果驱动程序不运行,但芯片是正常的,可以通过i2c控制,
  • --在1a地址,如果芯片关闭或其i2c地址实际上不是1a

有几种方法可以从用户空间控制GPIO,但是您试图控制的是什么?Linux可以使用GPIO作为LED, key, interrupt等。

sysfs是"老"吗?控制gpio的方法。它是有效的,而且还在维护中。实际上,您在/sys目录中编写节点。在c中,写文件是一个简单的过程。如果你愿意,你可以先在Shell中测试写文件。

$ echo 7 > /sys/class/gpio/export 
$ echo "out" > /sys/class/gpio/gpio7/direction 
$ echo 1 > /sys/class/gpio/gpio7/value #turn on 
$ echo 0 > /sys/class/gpio/gpio7/value #turn off

有一种访问GPIO的新方法。您可以打开/dev/chip并进行一些IOCTL调用。包含#include <linux/gpio.h>然后

  • GPIO_GET_LINEHANDLE_IOCTL,查看当前状态
  • GPIOHANDLE_GET_LINE_VALUES_IOCTL然后读取
  • GPIOHANDLE_SET_LINE_VALUES_IOCTL写入

您可以使用使用相同接口的Shell程序来测试它。

$ gpiodetect
$ gpioinfo
$ gpioset

我从来没有这样做过,但是这里有一个示例工具可以这样做。在5.9之后的内核中,你也可以使用#include "gpio-utils.h"

最新更新