Linux 下的 GPIO 控制指南
在 Linux 嵌入式开发中,GPIO (General Purpose Input/Output) 是最基础的外设,用于控制 LED、读取按键状态、驱动继电器等,在 Linux 系统中,操作 GPIO 主要有两种主流方式:传统的 Sysfs 接口 和现代推荐的 libgpiod 接口。
Sysfs 接口(传统方式)
Sysfs 是一种基于文件系统的交互方式,通过读写 /sys/class/gpio 目录下的文件来控制引脚,虽然这种方式在较新的内核中已被标记为 deprecated(弃用),但在许多旧版嵌入式系统中仍然非常常见。
操作步骤:
- 导出引脚:
通过向export文件写入引脚编号,使该引脚在 sysfs 中可见。
echo 18 > /sys/class/gpio/export - 设置方向:
在导出的引脚目录下,通过direction文件设置输入或输出。- 设置为输出:
echo out > /sys/class/gpio/gpio18/direction - 设置为输入:
echo in > /sys/class/gpio/gpio18/direction
- 设置为输出:
- 写入/读取电平:
- 输出高电平:
echo 1 > /sys/class/gpio/gpio18/value - 输出低电平:
echo 0 > /sys/class/gpio/gpio18/value - 读取电平:
cat /sys/class/gpio/gpio18/value
- 输出高电平:
- 取消导出:
操作完成后,释放引脚。
echo 18 > /sys/class/gpio/unexport
缺点:
- 性能较低:每次操作都需要进行文件系统调用。
- 非原子性:在多进程环境下,容易出现竞争条件。
- 资源占用:由于是基于文件的,管理起来不够灵活。
libgpiod 接口(现代推荐方式)
libgpiod 是目前 Linux 内核推荐的标准方式,它通过字符设备(/dev/gpiochipX)直接与内核通信,效率更高,且支持更复杂的控制逻辑。
核心工具命令:
使用 libgpiod,你不再需要频繁地 echo 文件,而是使用专门的命令行工具:
- gpiodetect:列出系统中所有的 GPIO 控制器(chip)。
- gpioinfo:查看特定 GPIO 控制器上所有引脚的状态和配置。
- gpioset:设置 GPIO 引脚的电平。
- 示例:
gpioset gpiochip4 12=1(将 chip4 的第 12 号引脚设为高电平)。
- 示例:
- gpioget:读取 GPIO 引脚的电平。
- 示例:
gpioget gpiochip4 12
- 示例:
- gpiomon:监控 GPIO 引脚的状态变化(中断触发)。
- 示例:
gpiomon gpiochip4 12
- 示例:
优点:
- 高效性:直接通过 ioctl 系统调用,减少了文件系统开销。
- 原子性:支持同时对多个引脚进行原子操作。
- 事件驱动:通过
gpiomon可以非常方便地处理中断事件。
两种方式的对比总结
| 特性 | Sysfs 接口 | libgpiod 接口 |
|---|---|---|
| 内核状态 | 已弃用 (Deprecated) | 当前标准 (Recommended) |
| 操作对象 |
|
/dev/gpiochipX |
| 性能 | 较低 (文件系统开销) | 高 (直接系统调用) |
| 中断处理 | 较复杂 (需通过 epoll 监听文件) | 简单 (原生支持 gpiomon) |
| 安全性 | 容易产生竞态条件 | 支持原子操作,更安全 |
开发建议
- 如果你在维护旧的嵌入式设备,或者在学习基础原理,可以了解 Sysfs。
- 如果你在进行新项目的开发,或者追求高性能和稳定性,请务必学习并使用 libgpiod。
- 在编写 C/C++ 程序时,建议直接调用
libgpiod提供的 API,而不是通过system("echo ...")来调用命令行,以获得最佳性能。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/489462.html



