嵌入式 Linux :Pinctrl 与 GPIO 子系统详解
Pinctrl(Pin Control)子系统是 Linux 内核中用于管理芯片管脚复用的框架。它负责配置芯片的管脚功能,例如将某个管脚配置为 GPIO、UART、I2C 等。管脚复用配置:将芯片的物理管脚配置为特定的功能。管脚电气属性配置:配置管脚的电气属性,如上拉、下拉、驱动能力等。GPIO(General Purpose Input/Output)子系统是 Linux 内核中用于管理通用输入
文章目录
引言
在嵌入式 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 管脚的控制。通过合理使用这两个子系统,可以简化硬件资源的配置和管理,提高系统的可移植性和可维护性。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)