我是靠谱客的博主 舒适乐曲,最近开发中收集的这篇文章主要介绍第八章 linux-pinctrl和gpio子系统第八章 linux-pinctrl和gpio子系统前言一、pinctrl子系统二、gpio子系统三、pinctrl与gpio子系统的使用pinctrl与gpio子系统内核实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

第八章 linux-pinctrl和gpio子系统


文章目录

  • 第八章 linux-pinctrl和gpio子系统
  • 前言
  • 一、pinctrl子系统
  • 二、gpio子系统
  • 三、pinctrl与gpio子系统的使用
    • pinctrl使用模板
    • gpio模板
  • pinctrl与gpio子系统内核实现


前言

原始字符设备驱动,patform框架,设备树这三种方法来点亮led灯的原理都是配置gpio寄存器。但在实际开发中,需要用到的引脚非常多。都是用前面讲到的方法不显示,麻烦。实际开发中我们常用pinctrl和gpio子系统来进行GPIO驱动开发。


一、pinctrl子系统

传统的配置 pin 的方式就是直接操作相应的寄存器,但是这种配置方式比较繁琐、而且容易出问题(比如 pin 功能冲突)。而pinctrl子系统就是为了解决这种问题而引入的,pinctrl子系统的主要工作内容:
1.获取设备树中pin的信息
2.依据获取到的pin信息设置pin的复用功能
3.依据获取到的pin信息设置pin的电气属性。
使用时我们只需要在设备树里面设置好某个 pin 的相关属性即可,其他的初始化工作均由 pinctrl 子系统来完成。例如:

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_hog_1>;
	imx6ul-evk {
		 pinctrl_led: ledgrp {
			 fsl,pins = <
				 MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */
			 >;
		 };

搜索“pinctrl_led”就会找到 pin引脚的gpio设置:

	gpioled {
		 #address-cells = <1>;
		 #size-cells = <1>;
		 compatible = "atkalpha-gpioled";
		 pinctrl-names = "default";
		 pinctrl-0 = <&pinctrl_led>;
		 led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
		 status = "okay";
	 };

注意:pinctrl_led节点和gpioled 节点是我自己添加上去的,不是原来就有的。
我们先说明pinctrl子系统。gpio1_3在这里我们用来点亮led灯:

MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 

这是一个宏定义,在arch/arm/boot/dts/imx6ul-pinfunc.h中可以找到:

#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03                          0x0068 0x02F4 0x0000 0x5 0x0

后面跟着5个数字,为该宏定义的具体值。

<mux_reg conf_reg input_reg mux_mode input_val>

0x0068 :mux_reg 寄存器偏移地址,设备树中的 iomuxc 节点就是 IOMUXC 外设对应的节点 , 根 据 其 reg 属 性 可 知 IOMUXC 外 设 寄 存 器 起 始 地 址 为 0x020e0000 。 因 此0x020e0000+0x0068 =0x020e0068, MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 寄存器地址正 好 是 0x020e0068,
在这里插入图片描述
0x020e0000+mux_reg 就是 PIN 的复用寄存器地址。
0x02F4 : conf_reg 寄存器偏移地址,和 mux_reg 一样, 0x020e0000+0x02F4 =0x020e02F4c,这个就是寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址。
在这里插入图片描述

0x0000: input_reg 寄存器偏移地址,有些外设有 input_reg 寄存器,有 input_reg 寄存器的外设需要配置 input_reg 寄存器。没有的话就不需要设置, GPIO1_IO03这个 PIN 在做GPIO1_IO03的时候是没有 input_reg 寄存器,因此这里 intput_reg 是无效的。
0x5 : mux_reg 寄 存 器 值 , 在 这 里 就 相 当 于 设 置MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 寄存器为 0x5,也即是设置 GPIO1_IO03这个 PIN 复用为 GPIO1_IO03。
0x0: input_reg 寄存器值,在这里无效。至于pin引脚的电气属性,由我们自行设置:

MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */

0x10B0 设置的就是 conf_reg 寄存器值,在这里就相当于设置寄存器MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 的值为 0x10B0 。

二、gpio子系统

pinctrl 子系统重点是设置 PIN(有的 SOC 叫做 PAD)的复用和电气属性,如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系统,gpio 子系统就是用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO为输入输出,读取 GPIO 的值等。

	gpioled {
		 #address-cells = <1>;
		 #size-cells = <1>;
		 compatible = "atkalpha-gpioled";
		 pinctrl-names = "default";
		 pinctrl-0 = <&pinctrl_led>;
		 led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
		 status = "okay";
	 };

pinctrl-0 属性设置 LED 灯所使用的 PIN 对应的 pinctrl 节点。led-gpio 属性指定了 LED 灯所使用的 GPIO,在这里就是 GPIO1 的 IO03,低电平有效。稍后编写驱动程序的时候会获取 led-gpio 属性的内容来得到 GPIO 编号,因为 gpio 子系统的 API 操作函数需要 GPIO 编号。

三、pinctrl与gpio子系统的使用

pinctrl使用模板

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

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

2、添加“fsl,pins”属性
设备树是通过属性来保存信息的,因此我们需要添加一个属性,属性名字一定要为“fsl,pins”,因为对于 I.MX 系列 SOC 而言, pinctrl 驱动程序是通过读取“fsl,pins”属性值来获取 PIN 的配置信息,完成以后如下所示:

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 是具体设置值*/
 >;

gpio模板

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

test {
 /*节点内容*/
 }

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

test {
 pinctrl-names = "default";
 pinctrl-0 = <&pinctrl_test>;
 /* 其他节点内容 */
 };

添加 pinctrl-names 属性,此属性描述 pinctrl 名字为“default”。
添加 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>;
 }

pinctrl与gpio子系统内核实现

最后

以上就是舒适乐曲为你收集整理的第八章 linux-pinctrl和gpio子系统第八章 linux-pinctrl和gpio子系统前言一、pinctrl子系统二、gpio子系统三、pinctrl与gpio子系统的使用pinctrl与gpio子系统内核实现的全部内容,希望文章能够帮你解决第八章 linux-pinctrl和gpio子系统第八章 linux-pinctrl和gpio子系统前言一、pinctrl子系统二、gpio子系统三、pinctrl与gpio子系统的使用pinctrl与gpio子系统内核实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部