Princtrl子系统和gpio子系统的简单使用

文章详细介绍了Linux内核中的pinctrl子系统和GPIO子系统的功能及工作原理。pinctrl子系统负责根据设备树中的信息设置PIN的复用功能和电气特性;GPIO子系统提供初始化GPIO和相关API,简化驱动开发者对GPIO的操作。还阐述了如何在设备树中添加pinctrl和GPIO节点模板,并列举了GPIO子系统的API函数及其使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Princtrl子系统的主要作用:

  1. 获取设备树中pin信息;
  2. 根据获取到的pin信息来设置pin的复用功能;
  3. 根据获取到的pin信息来设置pin的电气特性,比如上下拉、速度等。
    只需要在设备树里面设置好某个 pin 的相关属性,其他的初始化工作均由 pinctrl 子系统来完成, pinctrl 子系统源码目录为 drivers/pinctrl。

2、向设备树中添加pinctrl节点模板(以imx6ull为例):

1、创建对应的节点:
同一个外设的 PIN 都放到一个节点里面,打开 imx6ull-emmc.dts,在 iomuxc 节点中的“imx6ul-evk”子节点下添加“pinctrl_test”节点。添加完成以后如下所示:

pinctrl_test: testgrp {
	/* 具体的 PIN 信息 */
};

2、添加"fsl,pins"属性:
设备树是通过属性来保存信息的,因此我们需要添加一个属性,属性名字一定要为“fsl,pins”。

pinctrl_test: testgrp {
	fsl,pins = <
	/* 设备所使用的 PIN 配置信息 */
	>;
};

3、在"fsl,pins"属性中添加PIN配置信息:
在“fsl,pins”属性中添加具体的 PIN 配置信息。

pinctrl_test: testgrp {
	fsl,pins = <
	MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 config /*config 是具体设置值*/
	>;
};

3、GPIO子系统

GPIO子系统的作用:用于初始化GPIO并且提供相应的API函数,如:设置GPIO为输入输出,读取GPIO等。
GPIO子系统的主要目的:方便驱动开发者使用GPIO。
驱动开发者在设备树中添加 GPIO相关信息,然后就可以在驱动程序中使用 GPIO子系统提供的 API函数来操作 GPIO, Linux 内核向驱动开发者屏蔽掉了 GPIO 的设置过程,极大的方便了驱动开发者使用 GPIO。

4、gpio子系统API函数:

gpio子系统提供以下几个常用的API函数:
1、gpio_request函数:
gpio_request 函数用于申请一个 GPIO 管脚,在使用一个 GPIO 之前一定要使用 gpio_request进行申请,函数原型如下:

int gpio_request(unsigned gpio, const char *label)

gpio:要申请的 gpio 标号,使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信息,此函数会返回这个 GPIO 的标号。
label:给 gpio 设置个名字。
返回值: 0,申请成功;其他值,申请失败。
2、gpio_free函数:
如果不使用某个 GPIO 了,那么就可以调用 gpio_free 函数进行释放。函数原型如下:

void gpio_free(unsigned gpio)

gpio:要释放的 gpio 标号。
返回值: 无。
3、 gpio_direction_input 函数:
此函数用于设置某个 GPIO 为输入,函数原型如下所示:

int gpio_direction_input(unsigned gpio)

gpio:要设置为输入的 GPIO 标号。
返回值: 0,设置成功;负值,设置失败。
4、 gpio_direction_output 函数:
此函数用于设置某个 GPIO 为输出,并且设置默认输出值,函数原型如下:

int gpio_direction_output(unsigned gpio, int value)

gpio:要设置为输出的 GPIO 标号。
value: GPIO 默认输出值。
返回值: 0,设置成功;负值,设置失败。
5、 gpio_get_value 函数:
此函数用于获取某个 GPIO 的值(0 或 1),此函数是个宏,定义所示:

#define gpio_get_value __gpio_get_value
int __gpio_get_value(unsigned gpio)

gpio:要获取的 GPIO 标号。
返回值: 非负值,得到的 GPIO 值;负值,获取失败。
6、 gpio_set_value 函数
此函数用于设置某个 GPIO 的值,此函数是个宏,定义如下

#define gpio_set_value __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)

gpio:要设置的 GPIO 标号。
value: 要设置的值。
返回值: 无

5、设备树中添加gpio节点模板:

1、创建 test 设备节点:
在根节点“/”下创建 test 设备子节点,如下所示:

test {
	/* 节点内容 */
}

2、添加 pinctrl 信息:
上面我们创建了 pinctrl_test 节点,此节点描述了 test 设备所使用的 GPIO1_IO00 这个 PIN 的信息,我们要将这节点添加到 test 设备节点中,如下所示:

test {
	pinctrl-names = "default";		//添加 pinctrl-names 属性,此属性描述 pinctrl 名字为“default”
	pinctrl-0 = <&pinctrl_test>;	//添加 pinctrl-0 节点,此节点引用上面创建的 pinctrl_test 节点,表示 tset 设备的所使用的 PIN 信息保存在 pinctrl_test 节点中
	/* 其他节点内容 */
};

3、添加 GPIO 属性信息:
在 test 节点中添加 GPIO 属性信息,表明 test 所使用的 GPIO 是哪个引脚,添加完成以后如下所示:

test {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_test>;
	gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;	//test 设备所使用的 gpio
};

6、与gpio相关的OF函数:

1、 of_gpio_named_count 函数:
of_gpio_named_count 函数用于获取设备树某个属性里面定义了几个 GPIO 信息,要注意的是空的 GPIO 信息也会被统计到,此函数原型如下:

int of_gpio_named_count(struct device_node *np, const char *propname)

np:设备节点。
propname:要统计的 GPIO 属性。
返回值: 正值,统计到的 GPIO 数量;负值,失败。
2、 of_gpio_count 函数
和 of_gpio_named_count 函数一样,但是不同的地方在于,此函数统计的是“gpios”这个属性的 GPIO 数量,而 of_gpio_named_count 函数可以统计任意属性的 GPIO 信息,函数原型如下所示:

int of_gpio_count(struct device_node *np)

np:设备节点。
返回值: 正值,统计到的 GPIO 数量;负值,失败。
3、 of_get_named_gpio 函数
此函数获取 GPIO 编号,因为 Linux 内核中关于 GPIO 的 API 函数都要使用 GPIO 编号,此函数会将设备树中类似<&gpio5 7 GPIO_ACTIVE_LOW>的属性信息转换为对应的 GPIO 编号,函数原型如下:

int of_get_named_gpio(struct device_node *np,
						const char *propname,
						int index)

np:设备节点。
propname:包含要获取 GPIO 信息的属性名。
index: GPIO 索引,因为一个属性里面可能包含多个 GPIO,此参数指定要获取哪个 GPIO的编号,如果只有一个 GPIO 信息的话此参数为 0。
返回值: 正值,获取到的 GPIO 编号;负值,失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值