在 Linux 的 pinctrl 子系统中,引脚组(Groups) 和 功能(Functions) 是两个核心抽象概念,用于描述硬件引脚的逻辑配置。以下是它们的详细解析及协作关系:
1. 引脚组(Groups)
1.1 定义
- 引脚组是物理引脚的逻辑集合,表示一组需要统一配置的引脚。
- 例如:SPI 控制器需要
SCK
,MISO
,MOSI
,CS
四个引脚,可定义为一个引脚组spi0_pins
。
1.2 关键特性
- 原子性配置:对引脚组的配置(如复用、电气参数)会一次性应用到组内所有引脚。
- 硬件无关性:通过设备树定义,驱动代码无需关心具体引脚编号。
- 动态切换:支持运行时切换引脚组状态(如从
default
切换到sleep
)。
1.3 设备树定义示例
spi0_pins: spi0-pins {
rockchip,pins = <
PINMUX_GPIO0_A0 // SCK
PINMUX_GPIO0_A1 // MISO
PINMUX_GPIO0_A2 // MOSI
PINMUX_GPIO0_A3 // CS
>;
rockchip,function = "spi0"; // 默认功能为 SPI
bias-pull-up; // 组内所有引脚启用上拉
};
2. 功能(Functions)
2.1 定义
- 功能表示引脚组的逻辑用途,即引脚被配置为执行特定外设任务(如 UART、I2C)或 GPIO。
- 例如:
spi0
功能表示将spi0_pins
引脚组配置为 SPI 控制器使用。
2.2 关键特性
- 复用控制:同一引脚组可被分配给不同功能(如
gpio
或spi0
)。 - 状态管理:功能可定义多个状态(如
default
/sleep
),支持动态切换。 - 驱动绑定:功能与具体外设驱动关联,驱动通过选择功能激活对应引脚配置。
2.3 设备树定义示例
spi0_function: spi0-function {
rockchip,groups = "spi0_pins"; // 关联到 spi0_pins 引脚组
rockchip,function = "spi0"; // 功能名称
rockchip,drive = <8>; // 驱动强度配置(可选)
};
3. 协作关系:Groups + Functions = 完整配置
3.1 配置流程
- 定义引脚组:在设备树中声明物理引脚集合及默认配置。
- 定义功能:将引脚组绑定到特定功能,并附加额外配置(如驱动强度)。
- 状态管理:为功能定义多个状态(如
default
/sleep
),实现动态切换。
3.2 驱动使用示例
// 1. 获取 pinctrl 设备
struct pinctrl *pctl = devm_pinctrl_get(&pdev->dev);
// 2. 查找功能(如 "spi0")
struct pinctrl_state *state_default = pinctrl_lookup_state(pctl, "default");
// 3. 选择功能,激活对应引脚配置
pinctrl_select_state(pctl, state_default);
4. 实际应用场景
4.1 外设初始化
- 场景:SPI 控制器驱动初始化时需配置引脚为 SPI 功能。
- 流程:
- 解析设备树中的
spi0_pins
引脚组和spi0_function
功能。 - 调用
pinctrl_select_state
激活spi0
功能。 - 硬件引脚自动配置为 SPI 模式(SCK/MISO/MOSI/CS)。
- 解析设备树中的
4.2 电源管理
- 场景:系统进入低功耗模式时需关闭未使用引脚的上拉。
- 流程:
- 定义
sleep
状态,禁用引脚组的bias-pull-up
。 - 通过
pinctrl_select_state
切换到sleep
状态。 - 硬件引脚进入低功耗配置。
- 定义
4.3 板级定制
- 场景:同一内核支持不同硬件变体(如开发板与量产板)。
- 流程:
- 为不同硬件版本编写设备树片段,定义差异化的引脚组和功能。
- 内核通过设备树自动适配,驱动代码无需修改。
5. 底层实现原理
5.1 数据结构关联
struct pinctrl_desc
:描述 pinctrl 控制器支持的引脚组和功能。struct pinctrl_map
:关联引脚组、功能与状态,形成配置链表。
5.2 状态切换逻辑
- 解析设备树:构建
pinctrl_map
链表,记录所有可能的配置。 - 选择状态:通过
pinctrl_select_state
遍历链表,找到匹配的配置。 - 配置硬件:调用底层驱动(如
pinctrl_ops
)写入寄存器,应用配置。
总结
- 引脚组(Groups):物理引脚的逻辑集合,定义配置的原子单元。
- 功能(Functions):引脚组的逻辑用途,绑定到具体外设或 GPIO。
- 协作关系:通过设备树定义配置,驱动通过选择功能激活引脚组配置,实现硬件资源的灵活管理。
这种设计使得 Linux 内核能够以统一的方式管理不同硬件平台的引脚,同时支持动态配置切换,显著提升了内核的可移植性和硬件适配能力。