从Linux4.8开始,可以使用libgpio软件包,而以往通过sysfs的GPIO控制方式逐渐被淘汰。libgpio是linux内核提供的GPIO控制库,允许用户在用户空间控制GPIO引脚,包括设置引脚的方向(输入/输出)、读取引脚状态等。要使用libgpio,需要在系统中进行安装:
sudo apt install libgpiod-dev // 安装开发库,其中包含GPIO控制代码头文件和开发工具
sudo apt install gpiod // 安装GPIO命令行工具
可以通过配置寄存器的方式,指定选择MIO端口为GPIO
查看寄存器的数据
root@phytium-Ubuntu:~# devmem2 0x281a0020
root@phytium-Ubuntu:~# devmem2 0x281a0020
/dev/mem opened.
Memory mapped at address 0xffff8ca18000.
Value at address 0x281A0020 (0xffff8ca18020): 0x0
配置寄存器,写入数据 0x02
root@phytium-Ubuntu:~# devmem2 0x281a0020 w 2
/dev/mem opened.
Memory mapped at address 0xffff89a35000.
Value at address 0x281A0020 (0xffff89a35020): 0x0
Written 0x2; readback 0x2
将寄存器配置为普通GPIO,就可以使用sysfs或libgpio控制引脚电平状态。
查看系统中所有的GPIO信息
gpiodetect // 列举系统中的所有GPIO控制器
gpioinfo gpiochip4 // 查看gpiochip4控制器的引脚信息
如果系统同时安装了sysfs系统控制GPIO,则会显示被sysfs使用的GPIO端口。
如果端口已经被sysfs使用( sys/class/gpio),则不能使用GPIO控制IO口状态。需要先取消sysfs对相应GPIO的占用。
root@phytium-Ubuntu:~# echo 503 > /sys/class/gpio/unexport
设置相应的端口输出高电平
root@phytium-Ubuntu:~# gpioset gpiochip0 7=1
测量输出IO为高电平
读取引脚引脚电平
root@phytium-Ubuntu:~# gpioget gpiochip0 7
1
root@phytium-Ubuntu:~#
root@phytium-Ubuntu:~# gpioset gpiochip0 7=0
测量输出IO为低电平
读取引脚引脚电平(读取瞬间变高)
root@phytium-Ubuntu:~# gpioget gpiochip0 7
1
root@phytium-Ubuntu:~#
libgpio编程方式
gpiolib的头文件位于/usr/include/gpiod.h,它定义了用户访问GPIO的函数、结构和符号。根据调用其中的函数,可以完成对GPIO的控制。以下是一个简单的示例:
#include <stdio.h>
#include <gpiod.h>
int main()
{
struct gpiod_chip *chip;
struct gpiod_line *line;
int retflag = 0;
// 获取gpio4控制器
chip = gpiod_chip_open("/dev/gpiochip4");
if (!chip) {
printf("Failed to open chip");
return -1;
}
// 获取gpio4_13引脚
line = gpiod_chip_get_line(chip, 13);
if (!line) {
printf("Failed to get line");
retflag = -1;
goto chip_close;
}
// 将gpio4_13引脚设置为输出
int ret = gpiod_line_request_output(line, "ExampleOutput", GPIOD_LINE_ACTIVE_STATE_LOW);
if (ret < 0) {
printf("Failed to request output");
retflag = -1;
goto line_release;
}
// 设置 GPIO 引脚状态为高电平
ret = gpiod_line_set_value(line, 1);
if (ret < 0) {
printf("Failed to set value");
retflag = -1;
goto line_release;
}
// 读取 GPIO 引脚状态
int value = gpiod_line_get_value(line);
if (value < 0) {
printf("Failed to get value");
retflag = -1;
}
line_release:
gpiod_line_release(line);
chip_close:
gpiod_chip_close(chip);
return retflag;
}
编译程序,需要添加 -lgpiod 指定库文件。
gcc -o libgpio libgpio.c -lgpiod