简介

GPIO 接口

此目录中的文档提供了关于如何在驱动程序中访问 GPIO 以及如何为提供 GPIO 的设备编写驱动程序的详细说明。

什么是 GPIO?

“通用输入/输出”(GPIO) 是一种灵活的软件控制数字信号。 它们由多种芯片提供,并且嵌入式和定制硬件开发的 Linux 开发人员对此很熟悉。 每个 GPIO 代表连接到特定引脚或球栅阵列 (BGA) 封装上的“球”的一位。 电路板原理图显示了哪些外部硬件连接到哪些 GPIO。 可以通用地编写驱动程序,以便电路板设置代码将此类引脚配置数据传递给驱动程序。

片上系统 (SOC) 处理器严重依赖 GPIO。 在某些情况下,每个非专用引脚都可以配置为 GPIO; 大多数芯片至少有几十个。 可编程逻辑设备(如 FPGA)可以轻松提供 GPIO; 多功能芯片(如电源管理器和音频编解码器)通常有一些此类引脚,以帮助解决 SOC 上的引脚稀缺问题; 并且还有使用 I2C 或 SPI 串行总线连接的“GPIO 扩展器”芯片。 大多数 PC 南桥都有几十个支持 GPIO 的引脚(只有 BIOS 固件知道它们是如何使用的)。

GPIO 的确切功能因系统而异。 常见选项

  • 输出值可写(高=1,低=0)。 有些芯片还具有关于如何驱动该值的选项,因此例如,可能只驱动一个值,从而支持“线或”以及类似的其他值方案(特别是“开漏”信令)。

  • 输入值同样是可读的(1, 0)。 有些芯片支持回读配置为“输出”的引脚,这在“线或”情况下非常有用(以支持双向信令)。 GPIO 控制器可能具有输入去毛刺/防抖动逻辑,有时具有软件控制。

  • 输入通常可以用作 IRQ 信号,通常是边沿触发,但有时是电平触发。 此类 IRQ 可以配置为系统唤醒事件,以将系统从低功耗状态唤醒。

  • 通常,GPIO 可以根据不同产品板的需要配置为输入或输出; 也存在单向 GPIO。

  • 大多数 GPIO 可以在持有自旋锁时访问,但通过串行总线访问的 GPIO 通常无法访问。 有些系统同时支持这两种类型。

在给定的板上,每个 GPIO 都用于一个特定目的,例如监视 MMC/SD 卡的插入/移除、检测卡写保护状态、驱动 LED、配置收发器、位敲击串行总线、探测硬件看门狗、感应开关等等。

常见 GPIO 属性

这些属性通过 GPIO 接口的所有其他文档得到满足,理解它们很有用,特别是如果您需要定义 GPIO 映射。

高电平有效和低电平有效

自然假设 GPIO 在其输出信号为 1(“高”)时“有效”,而在其输出信号为 0(“低”)时无效。 但是,在实践中,GPIO 的信号可能会在到达其目的地之前被反转,或者设备可能会决定对“有效”的含义采用不同的约定。 这些决策对于设备驱动程序应该是透明的,因此可以将 GPIO 定义为高电平有效(“1”表示“有效”,默认值)或低电平有效(“0”表示“有效”),以便驱动程序只需要关心逻辑信号,而不必关心线路电平上发生的情况。

开漏和开源

有时,共享信号需要使用“开漏”(其中仅实际驱动低信号电平)或“开源”(其中仅驱动高信号电平)信令。 该术语适用于 CMOS 晶体管; “开集电极”用于 TTL。 上拉或下拉电阻会导致高或低信号电平。 这有时称为“线与”; 或者更实际地,从负逻辑(低=真)的角度来看,这是一个“线或”。

开漏信号的一个常见示例是共享的低电平有效 IRQ 线。 此外,双向数据总线信号有时使用开漏信号。

有些 GPIO 控制器直接支持开漏和开源输出; 许多不支持。 当您需要开漏信令但您的硬件不直接支持时,您可以使用一个通用的习惯用法,可以通过可用作输入或输出的任何 GPIO 引脚来模拟它

低电平gpiod_direction_output(gpio, 0) ... 这会驱动信号并覆盖上拉电阻。

高电平gpiod_direction_input(gpio) ... 这会关闭输出,因此上拉电阻(或某些其他设备)控制信号。

通过驱动高信号并将 GPIO 配置为低电平输入,可以将相同的逻辑应用于模拟开源信令。 此开漏/开源仿真可以由 GPIO 框架透明地处理。

如果您“驱动”信号为高电平,但 gpiod_get_value(gpio) 报告的值为低电平(在适当的上升时间过去后),您就知道某些其他组件正在将共享信号驱动为低电平。 这不一定是错误。 作为一个常见的例子,这就是 I2C 时钟被拉伸的方式:需要较慢时钟的从机延迟 SCK 的上升沿,并且 I2C 主机相应地调整其信令速率。