GPIO 控制和操作-使用命令通过sysfs文件系统控制GPIO
使用 sysfs 文件系统控制GPIO
文章目录
- 前言-需求
- 参考资料
- 一、内核配置
- 二、原理图分析-GPIO编号计算
- 三、使用sysfs控制接口控制GPIO
- GPIO 引脚导出与删除
- 核心概念
- /sys/class/gpio/export
- /sys/class/gpio/unexport
- 区别与联系
- 控制LED的导出export 操作
- export 导出失败问题
- GPIO export 导出后进行控制
- 基础文件active_low、direction、edge、value 描述
- active_low 极性反转设置
- direction GPIO方向设置
- edge 中断触发边沿
- value GPIO的电平值
- RK3568 命令控制LED灯
- 总结
前言-需求
- 了解 sysfs 如何通过命令控制GPIO
- 通过控制GPIO来控制LED灯亮灭
参考资料
原理图-复位开关和三极管点亮Led灯分析
之前分析过原理图,这里可以参考下,至少原理图要看得懂吧。
这里我们以RK3568 开发板,进行实例操作分析
一、内核配置
使用 sysfs 方式控制 gpio, 首先需要底层驱动的支持, 需要在 make menuconfig 图形化配置
界面中加入以下配置:
Device Drivers
->GPIO Support
->/sys/class/gpio/xxxx
二、原理图分析-GPIO编号计算
原理图,如下:这里通过GPIO标号 GPIO0_B7
,先要计算 pin 脚号是多少。
备注:
在早期接触GPIO编号和pin脚号计算的时候,有两个特别大的困难点
- 原理图看不懂,可能跟你的需求没关系,但是关联到这个是知识点 一脸懵逼
- pin脚号计算,不知道怎么计算,理解不了。 看了资料也理解不了。
当你仔细阅读资料,做多了,理解了pincontrol、sysfs、基本原理电路图 后,慢慢发现,这些都是1+1 等于2 一样简单,最最最基本的知识点。只是 初学者而言处处是一道坎!
RK3568 有 5 组 GPIO bank: GPIO0~GPIO4, 每组又以 A0~A7, B0~B7, C0~C7, D0~D7 作
为编号区分,常用以下公式计算引脚:
GPIO pin 脚计算公式: pin = bank * 32 + number //bank 为组号, number 为小组编号
GPIO 小组编号计算公式: number = group * 8 + X
GPIO0_PB7 pin 脚计算方法
bank = 0; //GPIO0_B7=> 0, bank ∈ [0,4]
group = 1; //GPIO0_B7 => 1, group ∈ {(A=0), (B=1), (C=2), (D=3)}
X = 7; //GPIO4_D7 => 5, X ∈ [0,7]
number = group * 8 + X = 1 * 8 + 7 =15
pin = bank*32 + number= 0 * 32 + 15 = 15;
三、使用sysfs控制接口控制GPIO
GPIO 引脚导出与删除
sysfs
控制接口为/sys/class/gpio/export
和 /sys/class/gpio/unexport
核心概念
在 Linux 的 GPIO Sysfs 接口 中,export 和 unexport 是两个用于 动态管理GPIO引脚用户空间访问权限 的虚拟文件。
GPIO Sysfs 接口: 这是内核提供的一个通过文件系统(通常在 /sys/class/gpio/ 目录下)来控制和配置GPIO的机制。
内核空间 vs 用户空间: 系统上所有的GPIO引脚默认由内核管理,用户空间的程序不能直接访问。export 和 unexport 就是连接内核空间和用户空间的“开关”。
/sys/class/gpio/export
-
作用: “申请”或“导出”一个GPIO引脚。
当你向 export 文件写入一个GPIO编号时,你是在告诉内核:“请把这个GPIO引脚的控制权交给我,我要在用户空间使用它 -
操作结果:
内核会收到这个请求,然后在 /sys/class/gpio/ 目录下动态创建一个新的目录,名字为 gpio<编号>。例如,你写入 18,就会创建 gpio18 目录。
在这个新创建的目录里,你会找到用于控制和配置这个引脚的文件,最主要的有:
direction: 设置方向(in 输入 / out 输出)
value: 读取(输入时)或设置(输出时)引脚的电平(0 低 / 1 高)
edge: 设置中断触发边沿(如 none, rising, falling, both),用于输入中断。
- 使用方法:
# 假设我们要使用 GPIO 18
echo 18 > /sys/class/gpio/export
执行后,检查是否成功:
ls /sys/class/gpio/
# 你会看到 export, unexport, gpio18 等文件和目录
/sys/class/gpio/unexport
- 作用: “ 释放”或“取消导出”一个GPIO引脚。
当你向 unexport 文件写入一个GPIO编号时,你是在告诉内核:“我用完这个GPIO引脚了,请收回控制权,并清理掉用户空间的访问接口。”
-
操作结果:
内核会收到这个请求,然后删除之前在 /sys/class/gpio/ 目录下为这个GPIO创建的目录(例如 gpio18)。之后,用户空间程序将无法再通过 /sys/class/gpio/gpio18/ 下的文件来访问这个引脚。 -
使用方法:
# 释放我们刚才使用的 GPIO 18
echo 18 > /sys/class/gpio/unexport
执行后,检查是否成功:
ls /sys/class/gpio/
# 你会发现 gpio18 目录已经消失了
区别与联系
特性 | export | unexport |
---|---|---|
核心作用 | 申请/导出 GPIO引脚 | 释放/取消导出 GPIO引脚 |
操作方向 | 内核 -> 用户空间 (开放权限) | 用户空间 -> 内核 (收回权限) |
操作对象 | 要操作的 GPIO编号 | 要释放的 GPIO编号 |
结果 | 在 /sys/class/gpio/ 下创建 gpioX 目录 | 从 /sys/class/gpio/ 下删除 gpioX 目录 |
类比 | 像 malloc() 或 new (申请内存) | 像 free() 或 delete (释放内存) |
文件性质 | 只写文件 | 只写文件 |
控制LED的导出export 操作
如上已经介绍了部分export 知识点,那么针对原理图 LED 灯的 GPIO0_B7 pin 引脚标号:15
所以,我们进行export 操作,结果如下:
export 导出失败问题
可能存在两个失败详细,export 导出不成功。
- 内核没有配置gpio 支持 ,如上内核配置说明部分
- 内核配置了,但是GPIO 标号对应的引脚编号已经被占用了,默认情况下被占用的,就要屏蔽掉。
报错如下:
解决方案:
路径:arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi 中屏蔽掉 work_led 相关 设备数配置
GPIO export 导出后进行控制
我们看导出结果,如上已经说明:
我们直接去软链接对应的gpio设备下看看:
基础文件active_low、direction、edge、value 描述
进行控制时候,首先要搞清楚这些文件是做什么的。
active_low 极性反转设置
含义:极性反转设置
0(默认):正常模式,value=1表示高电平,value=0表示低电平
1:反转模式,value=1表示低电平,value=0表示高电平
使用场景:
# 对于低电平有效的设备(如低电平触发的LED)
echo 1 > /sys/class/gpio/gpio4/active_low
echo 1 > /sys/class/gpio/gpio4/value # 实际输出低电平,点亮LED
direction GPIO方向设置
含义:GPIO方向设置
- in:输入模式(读取外部信号)
- out:输出模式(控制外部设备)
- low/high:输出模式并立即设置初始电平
示例
echo "in" > /sys/class/gpio/gpio4/direction # 设置为输入
echo "out" > /sys/class/gpio/gpio4/direction # 设置为输出
echo "low" > /sys/class/gpio/gpio4/direction # 输出模式,初始低电平
edge 中断触发边沿
含义:中断触发边沿(仅在输入模式下有效)
- none:无中断触发(默认)
- rising:上升沿触发(低电平→高电平)
- falling:下降沿触发(高电平→低电平)
- both:双边沿触发(上升和下降都触发)
示例:
echo "rising" > /sys/class/gpio/gpio4/edge # 设置上升沿中断
value GPIO的电平值
含义:GPIO的电平值
- 输出模式:写入1(高电平)或0(低电平)
- 输入模式:读取当前引脚电平状态
示例:
# 输出模式
echo 1 > /sys/class/gpio/gpio4/value # 输出高电平
echo 0 > /sys/class/gpio/gpio4/value # 输出低电平# 输入模式
cat /sys/class/gpio/gpio4/value # 读取当前电平
RK3568 命令控制LED灯
如上已经分析了基本的 文件表示意思,那么我们继续看原理图:
那么不就是GPIO0_B7 处于高电平的时候,三极管导通,LED灯亮。
实验:灭灯-亮灯
echo 0 > value 灭灯了查看 极性值: cat active_low 返回0 , 是默认的极性。 echo 1 > value 控制,亮灯了。
实验-更改极性
# echo 1 > active_low 更改极性echo 0 > value 设置value 值,灯居然亮了,和上面验证恰好相反的。
总结
- GPIO 基本知识了解,通过命令控制
- 使用命令通过sysfs文件系统控制GPIO,间接控制了LED灯亮、灭