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 */
struct gpio_desc {
struct gpio_device *gdev; // 所属的 GPIO 设备
unsigned long flags; // 状态标志位
const char *label; // 使用者标签
const char *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 */
struct gpio_chip {
const char *label; // 功能名称
struct gpio_device *gpiodev; // 内部状态
struct device *parent; // 父设备
struct module *owner;
int base; // GPIO 编号基数
u16 ngpio; // GPIO 数量
// 方向控制
int (*get_direction)(struct gpio_chip *gc, unsigned int offset);
int (*direction_input)(struct gpio_chip *gc, unsigned int offset);
int (*direction_output)(struct gpio_chip *gc, unsigned int offset, int value);
// 数据读写
int (*get)(struct gpio_chip *gc, unsigned int offset);
void (*set)(struct gpio_chip *gc, unsigned int offset, int value);
// 配置
int (*set_config)(struct gpio_chip *gc, unsigned int offset, unsigned long config);
// 中断相关
int (*to_irq)(struct gpio_chip *gc, unsigned int offset);
// 请求/释放
int (*request)(struct gpio_chip *gc, unsigned int offset);
void (*free)(struct gpio_chip *gc, unsigned int offset);
};
3. struct gpio_device - GPIO 设备
/* kernel/drivers/gpio/gpiolib.h */
struct gpio_device {
int id; // 设备 ID
struct device dev; // 设备模型
struct cdev chrdev; // 字符设备
struct gpio_chip *chip; // 指向 gpio_chip
struct gpio_desc *descs; // GPIO 描述符数组
int base; // 全局编号基数
u16 ngpio; // GPIO 数量
const char *label; // 描述性名称
struct list_head list; // 链入全局 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 回调函数 │
└─────────────────────────────────────────────────────────────────────┘
│
│ 读写寄存器
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 硬件寄存器 │
└─────────────────────────────────────────────────────────────────────┘
8.2.3 注册流程


2169

被折叠的 条评论
为什么被折叠?



