文章目录

在嵌入式 Linux 系统中,Pinctrl 和 GPIO 子系统是两个非常重要的组成部分。它们分别负责管脚复用配置和 GPIO 控制,为硬件资源的抽象和管理提供了强大的支持。本文将详细介绍 Pinctrl 和 GPIO 子系统的工作原理、使用方法以及它们之间的关系。


一、Pinctrl 子系统

1.1 什么是 Pinctrl 子系统?

Pinctrl(Pin Control)子系统是 Linux 内核中用于管理芯片管脚复用的框架。它负责配置芯片的管脚功能,例如将某个管脚配置为 GPIO、UART、I2C 等。Pinctrl 子系统的主要作用包括:

  • 管脚复用配置:将芯片的物理管脚配置为特定的功能。
  • 管脚电气属性配置:配置管脚的电气属性,如上拉、下拉、驱动能力等。

1.2 Pinctrl 子系统的工作原理

Pinctrl 子系统通过设备树来描述芯片的管脚配置信息。设备树中的 pinctrl 节点定义了管脚的复用配置和电气属性。内核在初始化时会解析这些配置,并将其应用到硬件上。

1.3 Pinctrl 子系统的设备树示例

以下是一个简单的 Pinctrl 设备树示例,即定义了一个名为pinctrl的引脚控制节点,其中包含用于配置UART功能和GPIO功能的子节点,分别设置了相应的引脚复用和上拉、无偏置电阻。

pinctrl: pinctrl@1000 {
    compatible = "nxp,pinctrl";
    reg = <0x1000 0x100>;

    uart0_pins: uart0_pins {
        pinmux = <0x01 0x02>; /* 配置管脚为 UART 功能 */
        bias-pull-up;
    };

    gpio_pins: gpio_pins {
        pinmux = <0x03 0x04>; /* 配置管脚为 GPIO 功能 */
        bias-disable;
    };
};

1.4 Pinctrl 子系统的使用

在驱动程序中,可以通过 pinctrl_get 和 pinctrl_select_state 函数来获取和设置管脚配置,如下即为通过设备树获取指定的pinctrl控制句柄,并查找名为uart0_pins的引脚状态,然后应用该状态到硬件上,以完成设备的UART引脚配置。

struct pinctrl *pinctrl;
struct pinctrl_state *state;

pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(pinctrl)) {
    return PTR_ERR(pinctrl);
}

state = pinctrl_lookup_state(pinctrl, "uart0_pins");
if (IS_ERR(state)) {
    return PTR_ERR(state);
}

pinctrl_select_state(pinctrl, state);

二、GPIO 子系统

2.1 什么是 GPIO 子系统?

GPIO(General Purpose Input/Output)子系统是 Linux 内核中用于管理通用输入输出管脚的框架。它提供了统一的接口来控制 GPIO 管脚,包括设置方向、读取输入、设置输出等。

2.2 GPIO 子系统的工作原理

GPIO 子系统通过设备树来描述 GPIO 管脚的信息。设备树中的 gpio 节点定义了 GPIO 管脚的编号和属性。内核在初始化时会解析这些信息,并将其注册到 GPIO 子系统中。

2.3 GPIO 子系统的设备树示例

以下是一个简单的 GPIO 设备树示例,定义了一个GPIO控制器节点,指定了兼容性、寄存器地址范围,并声明使用两个单元来描述GPIO引脚的配置。

gpio0: gpio@2000 {
    compatible = "nxp,gpio";
    reg = <0x2000 0x100>;
    gpio-controller;
    #gpio-cells = <2>;
};

2.4 GPIO 子系统的使用 

在驱动程序中,可以通过 gpio_request、gpio_direction_input、gpio_direction_output 等函数来控制 GPIO 管脚,如下为gpio引脚操作函数的简要使用代码示例。

int gpio = 10;

if (gpio_request(gpio, "my_gpio") < 0) {
    return -EBUSY;
}

gpio_direction_output(gpio, 1);
gpio_set_value(gpio, 0);

gpio_free(gpio);

 三、Pinctrl 与 GPIO 子系统的关系

Pinctrl 和 GPIO 子系统是紧密相关的。Pinctrl 子系统负责配置管脚的复用功能,而 GPIO 子系统负责控制已经配置为 GPIO 功能的管脚。在实际使用中,通常需要先通过 Pinctrl 子系统将管脚配置为 GPIO 功能,然后再通过 GPIO 子系统来控制这些管脚。

总结

Pinctrl 和 GPIO 子系统是嵌入式 Linux 系统中非常重要的组成部分。Pinctrl 子系统负责管脚复用配置,而 GPIO 子系统负责 GPIO 管脚的控制。通过合理使用这两个子系统,可以简化硬件资源的配置和管理,提高系统的可移植性和可维护性。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐