8. GPIO子系统
8.1 概述
GPIO(General Purpose Input/Output,通用输入输出)是嵌入式系统中最基础、最常用的外设接口之一。Linux 内核通过 GPIO 子系统为驱动开发者提供了一套统一的 API,屏蔽了不同 SoC 硬件实现的差异。
什么是 GPIO?
- 简单来说,GPIO 就是芯片引脚的软件控制能力
- 每个引脚可以独立配置为输入或输出模式
- 输出模式下可以控制引脚电平(高/低)
- 输入模式下可以读取引脚电平状态
为什么需要 GPIO 子系统?
┌─────────────────────────────────────────────────────────────┐ │ 驱动开发者 │ │ 只需调用 gpiod_set_value() 等统一 API │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ GPIO 子系统 (gpiolib) │ │ 提供抽象层,统一管理所有 GPIO 控制器 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ GPIO Controller 驱动 │ │ Rockchip GPIO │ NXP GPIO │ TI GPIO │ ... │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ 硬件 (SoC GPIO) │ └─────────────────────────────────────────────────────────────┘8.2 GPIOLIB 架构
8.2.1 核心数据结构
1. struct gpio_desc - GPIO 描述符
/* kernel/drivers/gpio/gpiolib.h */structgpio_desc{structgpio_device*gdev;// 所属的 GPIO 设备unsignedlongflags;// 状态标志位constchar*label;// 使用者标签constchar*name;// GPIO 名称// ... 其他字段};flags 标志位说明:
| 标志位 | 宏定义 | 说明 |
|---|---|---|
| 0 | FLAG_REQUESTED | GPIO 已被请求占用 |
| 1 | FLAG_IS_OUT | 方向为输出 |
| 6 | FLAG_ACTIVE_LOW | 低电平有效 |
| 7 | FLAG_OPEN_DRAIN | 开漏输出模式 |
| 8 | FLAG_OPEN_SOURCE | 开源输出模式 |
| 9 | FLAG_USED_AS_IRQ | 被用作中断 |
| 13 | FLAG_PULL_UP | 上拉使能 |
| 14 | FLAG_PULL_DOWN | 下拉使能 |
2. struct gpio_chip - GPIO 控制器
/* kernel/include/linux/gpio/driver.h */structgpio_chip{constchar*label;// 功能名称structgpio_device*gpiodev;// 内部状态structdevice*parent;// 父设备structmodule*owner;intbase;// GPIO 编号基数u16 ngpio;// GPIO 数量// 方向控制int(*get_direction)(structgpio_chip*gc,unsignedintoffset);int(*direction_input)(structgpio_chip*gc,unsignedintoffset);int(*direction_output)(structgpio_chip*gc,unsignedintoffset,intvalue);// 数据读写int(*get)(structgpio_chip*gc,unsignedintoffset);void(*set)(structgpio_chip*gc,unsignedintoffset,intvalue);// 配置int(*set_config)(structgpio_chip*gc,unsignedintoffset,unsignedlongconfig);// 中断相关int(*to_irq)(structgpio_chip*gc,unsignedintoffset);// 请求/释放int(*request)(structgpio_chip*gc,unsignedintoffset);void(*free)(structgpio_chip*gc,unsignedintoffset);};3. struct gpio_device - GPIO 设备
/* kernel/drivers/gpio/gpiolib.h */structgpio_device{intid;// 设备 IDstructdevicedev;// 设备模型structcdevchrdev;// 字符设备structgpio_chip*chip;// 指向 gpio_chipstructgpio_desc*descs;// GPIO 描述符数组intbase;// 全局编号基数u16 ngpio;// GPIO 数量constchar*label;// 描述性名称structlist_headlist;// 链入全局 gpio_devices 链表};8.2.2 架构层次图
┌─────────────────────────────────────────────────────────────────────┐ │ Consumer API 层 │ │ gpiod_get() / gpiod_set_value() / gpiod_get_value() │ └─────────────────────────────────────────────────────────────────────┘ │ │ 操作 gpio_desc ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ GPIOLIB 核心层 │ │ - GPIO 描述符管理 │ │ - 权限检查 │ │ - 统一编号空间 │ │ - 与设备树/ACPI 交互 │ └─────────────────────────────────────────────────────────────────────┘ │ │ 调用 gpio_chip ops ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ GPIO Controller 驱动层 │ │ gpio-rockchip.c │ gpio-pl061.c │ gpio-tegra.c │ ... │ │ 实现 gpio_chip 回调函数 │ └─────────────────────────────────────────────────────────────────────┘ │ │ 读写寄存器 ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 硬件寄存器 │ └─────────────────────────────────────────────────────────────────────┘