3. GPIO控制

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

Linux提供了GPIO子系统驱动框架,使用该驱动框架即可灵活地控制板子上的GPIO。

3.1. GPIO性能

  • 灌电流与拉电流为0-40mA可配置

3.2. GPIO命名

算能 Pin的ID按照 控制器(bank)+索引序号(pin) 组成。

  • 控制器和GPIO控制器数量⼀致

  • 控制器固定 A、B、C、D、PWR,对应GPIO控制器0、1、2、3、4

  • 索引序号固定 0、1、2、3、4、5、6、7…

sg200x具有5个控制器,作为GPIO功能时,端口⾏为由GPIO控制器寄存器配置。

GPIO 编号 = GPIO 组号值 + 偏移值

各控制器的GPIO值如下:

控制器

组号值

A

480

B

448

C

416

D

384

PWR

352

GPIOA_1表达的意思为控制器号为A,索引号为1。该引脚号的计算公式为 480+1=481

3.3. 使用GPIO sysfs接口控制IO

3.3.1. 命令行的方式

在Linux中,最常见的读写GPIO方式就是用GPIO sysfs interface, 是通过操作 /sys/class/gpio 目录下的 exportunexportgpio{N}/direction, gpio{N} /value (用实际引脚号替代{N})等文件实现的,经常出现shell脚本里面。 在kernel 4.8开始,加入了libgpiod的支持;

GPIO举例计算

引脚

控制器

索引号

计算结果

GPIOA_6

A

6

486 (480+6)

GPIOB_5

B

5

453 (448+5)

PWR_GPIO5

PWR

5

357 (32 x 0 + 8 x 3 + 6)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#以下所有操作均需要打开管理者权限使用
#使能引脚GPIOA_6
echo 486 > /sys/class/gpio/export

#设置引脚为输入模式
echo in > /sys/class/gpio/gpio486/direction
#读取引脚的值
cat /sys/class/gpio/gpio486/value

#设置引脚为输出模式
echo out > /sys/class/gpio/gpio486/direction
#设置引脚为低电平
echo 0 > /sys/class/gpio/gpio486/value
#设置引脚为高电平
echo 1 > /sys/class/gpio/gpio486/value

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

3.4. 使用libgpiod控制IO

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

想要使用libgpiod,需要在板卡上安装libgpiod库。

1
2
#安装gpiod 命令行工具
sudo apt install gpiod
  • gpiod工具的使用方法与sysfs接口的不同,gpiod是以控制器为单位,然后再详细到端口号和索引号,即gpiod使用两个数据确定引脚

GPIO举例计算

引脚

控制器

索引号

计算结果

GPIOA_6

A

6

0 6

GPIOB_5

B

5

2 5

PWR_GPIO5

PWR

4

4 5

常用的命令行如下,可使用 -h 查看命令相对应的使用说明(以GPIOA_6为例)

libgpiod命令

命令

作用

使用举例

说明

gpiodetect

列出所有的GPIO控制器

gpiodetect(无参数)

列出所有的GPIO控制器

gpioinfo

列出gpio控制器的引脚情况

gpioinfo 0

列出第一组控制器引脚组情况

gpioset

设置gpio

gpioset 0 6=0

设置第一组控制器编号6引脚为低电平

gpioget

获取gpio引脚状态

gpioget 0 6

获取第一组控制器编号6的引脚状态

gpiomon

监控gpio的状态

gpiomon 0 6

监控第一组控制器编号6的引脚状态

重要

算能 Pin的ID按照控制器(bank)+索引序号(pin) 组成。其中端口号和索引号会合并成一个数值传入到gpiod里去 并不是所有的引脚都能够使用libgpiod控制,例如心跳灯、wifi供电使能之类的一些已经被使用的引脚。

3.5. 使用debug接口查看IO

/sys/kernel/debug/gpio是一个特殊的接口,用于在Linux系统中进行GPIO(通用输入输出)调试和管理。 这个接口通常用于开发者在调试硬件时进行GPIO的配置、读取和监控。

1
2
#查看io状态
sudo cat /sys/kernel/debug/gpio
../../../_images/debug_gpio.jpg

可以从debug接口中查看IO的使用情况,输入/输出,当前电平,是否使用中断等。

例如gpio-353号脚,作为了wifi的使能脚,占用名字是”wifi_pwr_en”,这是因为设备树上定义了wifi_pwr_en节点,使用了”regulator-fixed”驱动配置了这个引脚,作用是启动快速拉高电平,那么驱动占用并且没有提供控制接口就不能在应用层进行控制。

例如gpio-452号脚,作为了用户按键引脚,占用名字是”usr_key”,这是因为使用“gpio-key”驱动配置了这个引脚,标签是”usr_key”,作用是输入中断检测,可见当前状态为“in hi IRQ”,表示输入、当前电平为高,中断触发。

例如gpio-486号脚,占用名字是”sysfs”,就是前面使用GPIO sysfs接口控制IO,控制GPIOA_6,使能引脚,设置为输入,没有使用中断,可见当前状态为高电平。

3.6. FAQs

Q1:当使用GPIO时出现 gpioset: error setting the GPIO line values: Device or resource busy 或者 -bash: echo: 写错误: 设备或资源忙

A1:说明GPIO被占用了,占用的原因可能是设备树里把该引脚作为gpio或者其他复用功能被使用了。