跳到主要内容

GPIO使用

GPIO 是 General Purpose I/O 的缩写,即通用输入输出端口,简单来说就是 MCU/CPU 可控制的引脚,这些引脚通常有多种功能,最基本的是高低电平输入检测和输出,部分引脚还会与主控器的片上外设绑定,如作为串口、I2C、网络、电压检测的通讯引脚。

RK3588 具有 5 个 GPIO 控制器,每个控制器可以控制 32 个 IO,作为 GPIO 功能时,端口行为由GPIO 控制器寄存器配置。Rockchip Pin 的 ID 按照控制器 (bank)+ 端口 (port)+ 索引序号 (pin) 组成。

  • 控制器(bank)和 GPIO 控制器数量一致
  • 端口固定 A、B、C 和 D,每个端口仅有 8 个索引号,(a=0,b=1,c=2,d=3)
  • 索引序号固定 0、1、2、3、4、5、6、7

开发板中预留20pin扩展,相应的接口如下

GPIO20pin

Net nameNUMNUMNet name
GPIO1_A0_dGPIO1_A0_3V312GPIO4_D5_3V3GPIO4_D5_d
GPIO1_A1_dGPIO1_A1_3V334GPIO4_D4_3V3GPIO4_D4_u
GPIO1_A2_dGPIO1_A2_3V356GPIO4_D3_3V3GPIO4_D3_u
GPIO1_A3_dGPIO1_A3_3V378GPIO4_D2_3V3GPIO4_D2_u
GPIO1_B4_uGPIO1_B4_3V3910GPIO1_C6_1V8GPIO1_C6_u
GND1112GND
GPIO1_B3_dGPIO1_B3_3V31314SARADC_VIN21V8 SARADC in
GPIO1_B2_dGPIO1_B2_3V31516VCC3V3_SYS
GPIO1_B1_dGPIO1_B1_3V31718VCC12V_DCIN
VCC5V0_SYS1920VCC12V_DCIN

GPIO sysfs接口控制

在 Linux 中,最常见的读写 GPIO 方式就是用 GPIO sysfs interface,是通过操作 /sys/class/gpio 目录下的 export 、unexport 、gpio{X}/direction, gpio{X} /value(用实际引脚号替代 {X})等文件实现的,经常出现 shell 脚本里面。在 kernel 4.8 开始,加入了 libgpiod 的支持;而原有基于 sysfs 的访问方式,将被逐渐放弃。

引脚控制器(bank)端口号(port)索引序号(pin)计算结果
GPIO1_A01A032x1+8x0+0=32
GPIO4_D54D532x4+8x3+5=157
GPIO1_B11B132x1+8x1+1=41
# 在超级用户权限下操作
# 使能引脚GPIO1_A0
echo 32 > /sys/class/gpio/export

# 设置引脚为输入模式
echo in > /sys/class/gpio/gpio32/direction

# 读取引脚的值
cat /sys/class/gpio/gpio32/value

# 设置引脚为输出模式
echo out > /sys/class/gpio/gpio32/direction

# 设置引脚为低电平
echo 0 > /sys/class/gpio/gpio32/value

# 设置引脚为高电平
echo 1 > /sys/class/gpio/gpio32/value

# 复位引脚
echo 32 > /sys/class/gpio/unexport

libgipo控制

libgpiod 是一种字符设备接口,GPIO 访问控制是通过操作字符设备文件(比如 /dev/gpiodchip0 )实现的,并通过 libgpiod 提供一些命令工具、c 库以及 python 封装。

# 安装 gpiod 命令行工具
sudo apt install gpiod

gpiod 工具的使用方法与 sysfs 接口的不同,gpiod 是以控制器(bank)为单位,然后再详细到端口号(port)和索引号(pin),即 gpiod 使用两个数据确定引脚

引脚控制器(bank)端口号(port)索引序号(pin)计算结果
GPIO1_A01A01,8x0+0=0
GPIO4_D54D54,8x3+5=29
GPIO1_B11B11,8x1+1=9
# 需要超级用户权限方可操作
# 列出所有的 GPIO 控制器
gpiodetect

# 列出 GPIO1 控制器的引脚情况
gpioinfo 1

# 设置 GPIO1_A0为高电平
gpioset 1 0=1

# 获取 GPIO1_A0 引脚状态
gpioget 1 0

# 监控 GPIO_A0 的状态(相当于输入状态)
gpiomon 1 0
注意

当 GPIO 被占用时,libgpiod 控制会出现“设备繁忙”进而无法使用