Linux驱动开发——(二)pinctrl和gpio子系统

目录

一、简介

二、修改设备树

[2.1 添加pinctrl节点](#2.1 添加pinctrl节点)

[2.2 添加LED设备节点](#2.2 添加LED设备节点)

[2.3 检查PIN是否被其他外设使用](#2.3 检查PIN是否被其他外设使用)

三、驱动代码

四、平台实验测试


一、简介

pinctrl子系统 简单来说就是用来配置PIN的复用和电气属性

对于使用者来讲,只需要在设备树里面设置好某个pin的相关属性即可,其他的初始
化工作均由pinctrl子系统来完成。pinctrl子系统源码目录为 drivers/pinctrl

gpio 子系统简单来说就是用来初始化GPIO并且提供相应的API

对于使用者来讲,在设备树中添加gpio相关信息,然后就可以在驱动程序中使用gpio子系统提供的 API函数来操作GPIO。


二、修改设备树

2.1 添加pinctrl节点

以I.MX6Ull为例,其LED灯使用了 GPIO1_IO03这个PIN,我们则需要打开设备树dts文件,在 iomuxc节点的imx6ul-evk子节点下创建一个名为" pinctrl_led"的子节点,节点内容如下所示:

复制代码
pinctrl_led: ledgrp { 
    fsl,pins = < 
        MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */ 
    >; 
};

第3行,将GPIO1_IO03这个PIN复用为GPIO1_IO03,电气属性值为0X10B0。

2.2 添加LED设备节点

在根节点"/"下创建 LED灯节点,节点名为"gpioled",节点内容如下:

复制代码
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"; 
};

第6行,pinctrl-0 属性设置LED灯所使用的PIN对应的pinctrl节点。

第7行,led-gpio属性指定了LED灯所使用的GPIO,在这里就是GPIO1的IO03,低电平有效。

2.3 检查PIN是否被其他外设使用

检查PIN有没有被其他外设使用包括两个方面:

①检查pinctrl设置。
②如果这个PIN配置为GPIO的话,检查这个GPIO有没有被别的外设使用。

对于①,可以全局检索"GPIO_IO03";对于②,可以全局检索"gpio1 3"。

找到全部对应的内容,将其屏蔽。

然后重新编译设备树,使用新的设备树启动Linux。


三、驱动代码

驱动入口函数加入以下代码:

复制代码
/* 设置LED所使用的GPIO */

	/* 1、获取设备节点:gpioled */

	gpioled.nd = of_find_node_by_path("/gpioled");

	if(gpioled.nd == NULL) {

		printk("gpioled node not find!\r\n");

		return -EINVAL;

	} else {

		printk("gpioled node find!\r\n");

	}



	/* 2、 获取设备树中的gpio属性,得到LED所使用的LED编号 */

	gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpio", 0);

	if(gpioled.led_gpio < 0) {

		printk("can't get led-gpio");

		return -EINVAL;

	}

	printk("led-gpio num = %d\r\n", gpioled.led_gpio);



	/* 3、设置GPIO1_IO03为输出,并且输出高电平,默认关闭LED灯 */

	ret = gpio_direction_output(gpioled.led_gpio, 1);

	if(ret < 0) {

		printk("can't set gpio!\r\n");

	}

对于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编号;负值,失败。


四、平台实验测试

如图:

输出正确,实现成功。

相关推荐
H_oRIZoN_2 小时前
Linux入门DAY42【51 单片机】DS18B20 数字温度传感器完整解析(单总线原理 + 时序 + 读取流程)
linux·单片机·linux应用编程
j7~2 小时前
【Linux网络加餐】(篇六)网络版计算器(上):模板方法模式、序列化与 JSON
linux·c++·json·序列化·反序列化·网络版计算机
流浪0012 小时前
Linux系统篇34——信号(六):信号处理期间又来了怎么办?——sigaction、sa_mask、可重入函数与 volatile
linux·运维·面试·操作系统·信号处理·信号
学烹饪的小胡桃2 小时前
资产设备管理系统 WGFIX 怎么设置https访问
linux·运维·服务器·网络·安全
邪修king3 小时前
Re:Linux系统篇(二十六):文件系统(二):Ext 文件系统底层详解:从 inode、块组到软硬链接,结合 Windows 讲透文件管理本质
android·java·linux
高亦真3 小时前
今天是学习嵌入式的第38天
linux·学习·算法
DYWorker0013 小时前
Linux驱动子系统:中断子系统 —— Consumer和Provider(005)
linux·驱动开发
草莓熊Lotso3 小时前
【Redis 进阶】主从复制深度解析:从配置落地到 PSYNC 同步原理
linux·开发语言·网络·数据库·redis·缓存·php
ShineWinsu4 小时前
对于Git:远程操作的超详细保姆级解析
linux·git·gitee·github·远程仓库·分布式版本控制系统·远程操作
小张成长计划..4 小时前
【Linux】21:进程间通信
linux