GPIO 子系统与 pinctrl 子系统解析

GPIO 子系统概述

GPIO(General Purpose Input/Output)子系统是 Linux 内核中用于管理通用输入/输出引脚的核心框架。GPIO 引脚可以配置为输入或输出模式,用于控制外设或读取传感器信号。GPIO 子系统通过标准化的接口(如 gpiod API)为开发者提供统一的访问方式,屏蔽硬件差异。

GPIO 子系统的核心功能包括引脚方向设置(输入/输出)、电平读写(高/低)、中断处理(边沿触发或电平触发)以及多路复用(复用为其他功能)。在设备树中,GPIO 节点通常通过 gpio-controller#gpio-cells 属性描述。

// 设备树示例
gpio0: gpio@0 {
    compatible = "vendor,gpio-controller";
    reg = <0x0 0x100>;
    gpio-controller;
    #gpio-cells = <2>;
};
pinctrl 子系统概述

pinctrl(Pin Control)子系统负责管理 SoC 的引脚复用和电气属性配置。现代 SoC 的引脚通常支持多种功能(如 GPIO、UART、I2C 等),pinctrl 子系统通过设备树或驱动程序动态配置引脚功能。

pinctrl 子系统的核心功能包括:

  • 引脚复用:配置引脚为特定功能(如 GPIO 或 UART)。
  • 电气属性配置:设置驱动强度、上下拉电阻、施密特触发等。
  • 状态管理:支持为不同设备状态(如休眠、唤醒)保存和恢复引脚配置。

设备树中的 pinctrl 节点示例:

pinctrl: pinctrl@1000 {
    compatible = "vendor,pinctrl";
    reg = <0x1000 0x200>;

    uart0_default: uart0_default {
        pins = "P1", "P2";
        function = "uart";
        bias-pull-up;
    };
};
GPIO 与 pinctrl 的协同工作

GPIO 子系统和 pinctrl 子系统紧密相关:

  1. 引脚初始化:pinctrl 子系统在设备启动时配置引脚的复用模式(如设置为 GPIO 功能)。
  2. 动态切换:驱动程序通过 pinctrl 接口临时切换引脚功能(如从 GPIO 切换到 SPI)。
  3. 电气隔离:pinctrl 确保 GPIO 引脚在未被使用时处于安全状态(如下拉或高阻态)。

在驱动开发中,通常先通过 pinctrl 绑定引脚功能,再通过 GPIO 子系统操作电平或中断。

实际应用示例

以下代码展示如何通过 pinctrl 和 GPIO 子系统控制 LED:

// 设备树片段
led_pins: led_pins {
    pins = "P3";
    function = "gpio";
    output-high;
};

led: led {
    compatible = "gpio-led";
    gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
    pinctrl-names = "default";
    pinctrl-0 = <&led_pins>;
};

// 驱动程序片段
struct gpio_desc *led;
led = gpiod_get(dev, NULL, GPIOD_OUT_HIGH);
gpiod_set_value(led, 0); // 拉低电平
总结

GPIO 子系统提供通用引脚操作接口,而 pinctrl 子系统管理引脚的复用和电气特性。两者协同工作,为嵌入式开发提供灵活的硬件控制能力。开发者应熟悉设备树配置和内核 API,以充分发挥其功能。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐