一、介绍gpio子系统
1.1基于gpio子系统框架
1.2基于gpio子系统API接口
#include <linux/of_gpio.h> int of_get_named_gpio(struct device_node *np, const char *propname, int index) 函数功能:获取gpio编号 参数: np:节点结构体指针 propname:属性名字 index:索引号 返回值: 成功获取到的gpio编号 失败返回<0 #include <linux/gpio.h> int gpio_request(unsigned gpio, const char *label); 函数功能:申请gpio编号 参数: gpio:获取到的gpio编号 label:NULL 返回值: 成功返回0 失败返回-1 int gpio_direction_input(unsigned gpio) 函数功能:设置gpio编号为输入模式 参数: gpio:获取到的gpio编号 返回值: 成功返回0 失败返回-1 int gpio_get_value(unsigned int gpio) 函数功能:读取gpio编号的值 参数: gpio:获取到的gpio编号 返回值: 返回值0:表示低电平 返回值1:表示高电平 int gpio_direction_output(unsigned gpio, int value) void gpio_set_value(unsigned int gpio, int value) 函数功能:设置gpio编号输出高低电平 参数: gpio:获取到的gpio编号 value: 写0:输出低电平 写1:输出高电平 返回值: 成功返回0 失败返回-1 void gpio_free(unsigned gpio); 函数功能:释放gpio编号 参数: gpio:申请的gpio编号 返回值:无
二、分析gpio子系统设备树
2.1引脚编号
2.2编写思路
- 通过以上框图分析可知三盏灯对应的引脚编号
- led1/led3与GPIOE控制器连接
- led2与GPIOF控制器连接
- 在linux内核中,所有的控制器已经编写实现
- 所以对于驱动工程师,只需要引用对应的控制器
2.3分析设备树
1、进入设备树目录,打开设备树源文件,搜索gpioe控制器
linux@ubuntu:~/linux-5.10.61$ cd arch/arm/boot/dts/
linux@ubuntu:~/linux-5.10.61/arch/arm/boot/dts$ vi stm32mp157a-fsmp1a.dts
linux@ubuntu:~/linux-5.10.61/arch/arm/boot/dts$ vi stm32mp157.dtsi
linux@ubuntu:~/linux-5.10.61/arch/arm/boot/dts$ vi stm32mp153.dtsi
linux@ubuntu:~/linux-5.10.61/arch/arm/boot/dts$ vi stm32mp151.dtsi
2、打开stm32mp151.dtsi, 搜索gpioe控制器,出现如下节点,分析gpioe节点
#address-cells = <1>;
#size-cells = <1>;
解释:address-cells和size-cells修饰子节点中固定含义键reg
address-cells:表示地址个数
size-cells:表示长度个数
gpioe: gpio@50006000 { =======> 将gpio@50006000起别名为gpioe
gpio-controller; =======> 空属性,没有实际含义,只起到标识作用
#gpio-cells = <2>; =======> 子节点在引用gpioe控制器时,需要填充2个成员
reg = <0x50006000 0x400>; =======> reg是固定含义键
clocks = <&rcc GPIOE>; =======> GPIOE组时钟使能
status = "disabled"; =======> GPIOE组控制器状态禁止
};
3、打开stm32mp15xxac-pinctrl.dtsi, 搜索gpioe控制器,出现如下节点,分析gpioe节点
linux@ubuntu:~/linux-5.10.61/arch/arm/boot/dts$ vi stm32mp15xxac-pinctrl.dtsi
gpioe: gpio@50006000 { =======> 将gpio@50006000起别名为gpioe
status = "okay"; =======> GPIOE组控制器状态使能
ngpios = <16>; =======> gpio每组有16个引脚
gpio-ranges = <&pinctrl 0 64 16>; =======> gpioe组引脚编号范围
};
4、通过以上分析,引用gpioe和gpiof组控制器 &gpioe &gpiof
三、编写gpio子系统设备树
3.1参考内核帮助文档
3.2编写gpio子系统设备树步骤
- 进入设备树目录,打开设备树源文件
- 添加gpio子系统设备树节点信息
- 编译设备树,并且拷贝到~/tftpboot目录下
- 开发板一定重新上电!!!!!!!!!
- 打开串口工具,开发板重新上电,加载最新设备树
四、gpio子系统练习
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
/*
myled{//基于gpio子系统设备树
led1 = <&gpioe 10 0>; //led1 PE10
led2 = <&gpiof 10 0>; //led2 PF10
led3 = <&gpioe 8 0>; //led3 PE8
};
*/
struct device_node* node;
unsigned int gpionum;
static int __init demo_init(void)
{
//获取myled节点
node = of_find_node_by_path("/myled");
if(node == NULL){
printk("of find node by path is error\n");
return -EIO;
}
//获取gpio编号
gpionum = of_get_named_gpio(node,"led1",0);
if(gpionum < 0){
printk("of get named gpio is error\n");
return -EIO;
}
//申请gpio编号
gpio_request(gpionum,NULL);
//设置gpio引脚输出高电平
gpio_direction_output(gpionum,1);
return 0;
}
static void __exit demo_exit(void)
{
//设置gpio引脚输出低电平
gpio_direction_output(gpionum,0);
//释放gpio编号
gpio_free(gpionum);
}
module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
标签:linux,控制器,0730,int,编号,gpioe,gpio,子系统 From: https://blog.csdn.net/slander_1120/article/details/140830063