您当前的位置: 首页 >  嵌入式

正点原子

暂无认证

  • 1浏览

    0关注

    382博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【正点原子MP157连载】第二十四章 设备树下的LED驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

正点原子 发布时间:2022-02-12 09:54:42 ,浏览量:1

1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-318813-1-1.html 4)正点原子官方B站:https://space.bilibili.com/394620890 5)正点原子STM32MP157技术交流群:691905614 在这里插入图片描述

第二十四章 设备树下的LED驱动实验

上一章我们详细的讲解了设备树语法以及在驱动开发中常用的OF函数,本章我们就开始第一个基于设备树的Linux驱动实验。本章在第二十二章实验的基础上完成,只是将其驱动开发改为设备树形式而已。

24.1 设备树LED驱动原理 在《第二十二章 新字符设备驱动实验》中,我们直接在驱动文件newchrled.c中定义有关寄存器物理地址,然后使用io_remap函数进行内存映射,得到对应的虚拟地址,最后操作寄存器对应的虚拟地址完成对GPIO的初始化。本章我们在第四十二章实验基础上完成,本章我们使用设备树来向Linux内核传递相关的寄存器物理地址,Linux驱动文件使用上一章讲解的OF函数从设备树中获取所需的属性值,然后使用获取到的属性值来初始化相关的IO。本章实验还是比较简单的,本章实验重点内容如下: ①、在stm32mp157d-atk.dts文件中创建相应的设备节点。 ②、编写驱动程序(在第二十二章实验基础上完成),获取设备树中的相关属性值。 ③、使用获取到的有关属性值来初始化LED所使用的GPIO。 24.2 硬件原理图分析 本实验的硬件原理参考21.2小节即可。 24.3 实验程序编写 24.3.1 修改设备树文件 在根节点“/”下创建一个名为“stm32mp1_led”的子节点,打开stm32mp157d-atk.dts文件,在根节点“/”最后面输入如下所示内容:

示例代码44.3.1.1 stm32mp1_led节点
1    stm32mp1_led {
2        compatible = "atkstm32mp1-led";
3        status = "okay";
4        reg = ; 	/* GPIOI_BSRR           	*/
10   };
第2行,属性compatible设置stm32mp1_led节点兼容为“atkstm32mp1-led”。
第3行,属性status设置状态为“okay”。
第4~9行,reg属性,非常重要!reg属性设置了驱动里面所要使用的寄存器物理地址,比如第4行的“0X50000A28 0X04”表示STM32MP1的RCC_MP_AHB4ENSETR寄存器,其中寄存器地址为0X50000A28,长度为4个字节。

设备树修改完成以后输入如下命令重新编译一下stm32mp157d-atk.dts: make dtbs 编译完成以后得到stm32mp157d-atk.dtb,使用新的stm32mp157d-atk.dtb启动Linux内核。Linux启动成功以后进入到/proc/device-tree/目录中查看是否有“stm32mp1_led”这个节点,结果如图24.3.1.1所示: 在这里插入图片描述

图24.3.1.1 stm32mp1_led节点 如果没有“stm32mp1_led”节点的话请重点检查下面两点: ①、检查设备树修改是否成功,也就是stm32mp1_led节点是否为根节点“/”的子节点。 ②、检查是否使用新的设备树启动的Linux内核。 可以进入到图24.3.1.1中的stm32mpl_led目录中,查看一下都有哪些属性文件,结果如图24.3.1.2所示: 在这里插入图片描述

图24.3.1.2 stm32mp1_led节点文件 大家可以用cat命令查看一下compatible、status等属性值是否和我们设置的一致。 24.3.2 LED灯驱动程序编写 设备树准备好以后就可以编写驱动程序了,本章实验在第二十二章实验驱动文件newchrled.c的基础上修改而来。新建名为“4_dtsled”文件夹,然后在4_dtsled文件夹里面创建vscode工程,工作区命名为“dtsled”。工程创建好以后新建dtsled.c文件,在dtsled.c里面输入如下内容:

示例代码24.3.2.1 dtsled.c文件内容
1   #include 
2   #include 
3   #include 
4   #include 
5   #include 
6   #include 
7   #include 
8   #include 
9   #include 
10  #include 
11  #include 
12  #include 
13  #include 
14  #include 
15  #include 
16 
17  /***************************************************************
18  Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
19  文件名  		: dtsled.c
20  作者      	: 正点原子Linux团队
21  版本      	: V1.0
22  描述      	: LED驱动文件。
23  其他      	: 无
24  论坛      	: www.openedv.com
25  日志      	: 初版V1.0 2020/12/19 正点原子Linux团队创建
26  ***************************************************************/
27  #define DTSLED_CNT       	1           	/* 设备号个数 	*/
28  #define DTSLED_NAME     	"dtsled"  	/* 名字 		*/
29  #define LEDOFF           	0           /* 关灯	 		*/
30  #define LEDON            	1           /* 开灯 			*/
31 
32  /* 映射后的寄存器虚拟地址指针 */
33  static void __iomem *MPU_AHB4_PERIPH_RCC_PI;
34  static void __iomem *GPIOI_MODER_PI;
35  static void __iomem *GPIOI_OTYPER_PI;
36  static void __iomem *GPIOI_OSPEEDR_PI;
37  static void __iomem *GPIOI_PUPDR_PI;
38  static void __iomem *GPIOI_BSRR_PI;
39 
40  /* dtsled设备结构体 */
41  struct dtsled_dev{
42      dev_t devid;            	/* 设备号     	*/
43      struct cdev cdev;       	/* cdev     	*/
44      struct class *class;   	/* 类      		*/
45      struct device *device;  	/* 设备    		*/
46      int major;              	/* 主设备号   	*/
47      int minor;              	/* 次设备号   	*/
48      struct device_node  *nd; /* 设备节点 	*/
49  };
50 
51  struct dtsled_dev dtsled;   	/* led设备 	*/
52 
53  /*
54   * @description  	: LED打开/关闭
55   * @param - sta  	: LEDON(0) 打开LED,LEDOFF(1) 关闭LED
56   * @return       	: 无
57   */
58  void led_switch(u8 sta)
59  {
60      u32 val = 0;
61      if(sta == LEDON) {
62          val = readl(GPIOI_BSRR_PI);
63          val |= (1             
关注
打赏
1665308814
查看更多评论
0.1348s