LV15-02-GPIO控制-01-基础知识

本文主要是GPIO控制——基础知识的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.6的64位版本(一开始使用的是16.04版本,后来进行了升级)
VMware® Workstation 17 Pro 17.0.0 build-20800274
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
https://elixir.bootlin.com/linux/latest/source 在线阅读linux kernel源码
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)

一、应用层如何操控 GPIO

与 LED 设备一样, GPIO 同样也是通过 sysfs 方式进行操控,进入到/sys/class/gpio 目录下,如下所示:

image-20240903075707130

可以看到该目录下包含两个文件 export、 unexport 以及 5 个 gpiochipX(X 等于 0、 32、 64、 96、 128)命名的文件夹。 接下来我们就来学习一下这些的用途。

1. gpiochipX

当前 SoC 所包含的 GPIO 控制器,我们知道 I.MX6UL/I.MX6ULL 一共包含了 5 个 GPIO控制器,分别为 GPIO1、 GPIO2、GPIO3、 GPIO4、 GPIO5,在这里分别对应 gpiochip0、 gpiochip32、gpiochip64、 gpiochip96、 gpiochip128 这 5 个文件夹, 每一个gpiochipX 文件夹用来管理一组 GPIO。随便进入到其中某个目录下,可以看到这些目录下包含了如下文件:

image-20240903075851275

在这个目录我们主要关注的是 base、 label、 ngpio 这三个属性文件,这三个属性文件均是只读、不可写。

  • base

与 gpiochipX 中的 X 相同,表示该控制器所管理的这组 GPIO 引脚中最小的编号。每一个 GPIO引脚都会有一个对应的编号, Linux 下通过这个编号来操控对应的 GPIO 引脚。

image-20240904073824362
  • label

该组 GPIO 对应的标签,也就是名字。

image-20240904073934293
  • ngpio

该控制器所管理的 GPIO 引脚的数量(所以引脚编号范围是: base ~ base+ngpio-1) 。

image-20240904074057803

对于给定的一个 GPIO 引脚,如何计算它在 sysfs 中对应的编号呢?其实非常简单,例如给定一个 GPIO引脚为 GPIO4_IO16,那它对应的编号是多少呢?首先我们要确定 GPIO4 对应于 gpiochip96,该组 GPIO 引脚的最小编号是 96(对应于 GPIO4_IO0),所以 GPIO4_IO16 对应的编号自然是 96 + 16 = 112;同理GPIO3_IO20 对应的编号是 64 + 20 = 84。

2. export

用于将指定编号的 GPIO 引脚导出。 在使用 GPIO 引脚之前,需要将其导出,导出成功之后才能使用它。 注意 export 文件是只写文件,不能读取,将一个指定的编号写入到 export 文件中即可将对应的 GPIO 引脚导出,如:

1
echo 0 > export # 导出编号为 0 的 GPIO 引脚(对于 I.MX6UL/I.MX6ULL 来说,也就是GPIO1_IO0)
image-20240904074600278

导出成功之后会发现在/sys/class/gpio 目录下生成了一个名为 gpio0 的文件夹(gpioX, X 表示对应的编号),如下图所示。这个文件夹就是导出来的 GPIO 引脚对应的文件夹,用于管理、控制该 GPIO 引脚,稍后再学习。

image-20240904074750867

控制 GPIO 引脚主要是通过 export 导出之后所生成的 gpioX(X 表示对应的编号)文件夹,在该文件夹目录下存在一些属性文件可用于控制 GPIO
引脚的输入、输出以及输出的电平状态等。

需要注意的是,并不是所有 GPIO 引脚都可以成功导出, 如果对应的 GPIO 已经在内核中被使用了, 那便无法成功导出,打印如下信息:

image-20240904075130193

这也就是意味着该引脚已经被内核使用了,例如某个驱动使用了该引脚,那么将无法导出成功。

3. unexport

将导出的 GPIO 引脚删除。当使用完 GPIO 引脚之后,我们需要将导出的引脚删除,同 样该文件也是只写文件、不可读,例如:

1
echo 0 > unexport # 删除导出的编号为 0 的 GPIO 引脚

删除成功之后,之前生成的 gpio0 文件夹就会消失:

image-20240904074926762

4. gpioX

将指定的编号写入到 export 文件中,可以导出指定编号的 GPIO 引脚,导出成功之后会在/sys/class/gpio目录下生成对应的 gpioX(X 表示 GPIO 的编号)文件夹,以前面所生成的 gpio0 为例,进入到 gpio0 目录,该目录下的文件如下所示:

image-20240904075323361

我们主要关心的文件是 active_low、 direction、 edge 以及 value 这四个属性文件,接下来分别学习这四个属性文件的作用:

  • direction

配置 GPIO 引脚为输入或输出模式。该文件可读、可写,读表示查看 GPIO 当前是输入还是输出模式,写表示将 GPIO 配置为输入或输出模式;读取或写入操作可取的值为”out”(输出模式)和”in”(输入模式),如下所示:

image-20240904075525666
  • value

在 GPIO 配置为输出模式下,向 value 文件写入”0”控制 GPIO 引脚输出低电平,写入”1”则控制 GPIO 引脚输出高电平。在输入模式下,读取 value 文件获取 GPIO 引脚当前的输入电平状态。例如:

1
2
3
4
5
6
# 获取 GPIO 引脚的输入电平状态
echo "in" > direction
cat value
# 控制 GPIO 引脚输出高电平
echo "out" > direction
echo "1" > value
image-20240904075727400
  • active_low

这个属性文件用于控制极性, 可读可写,默认情况下为 0,如:

1
2
3
4
5
6
7
8
9
10
11
# active_low 等于 0 时
echo "0" > active_low
echo "out" > direction
echo "1" > value # 输出高
echo "0" > value # 输出低

# active_low 等于 1 时
$ echo "1" > active_low
$ echo "out" > direction
$ echo "1" > value # 输出低
$ echo "0" > value # 输出高

由此看出, active_low 的作用已经非常明显了, 对于输入模式来说也同样适用。

  • edge

控制中断的触发模式,该文件可读可写。 在配置 GPIO 引脚的中断触发模式之前,需将其设置为输入模式:

1
2
3
4
echo "none" > edge      # 非中断引脚
echo "rising" > edge # 上升沿触发
echo "falling" > edge # 下降沿触发
echo "both" > edge # 边沿触发

当引脚被配置为中断后可以使用 poll()函数监听引脚的电平状态变化,在后面的示例中将进行学习。