
设备树就是DTS文件其内容是用于描述开发板的硬件信息,在之前编译Linux内核的时候生成的stm32mp157a-dk1.dtb就是Stm32mp157A-DK1板子的设备树,在mylinux/arch/arm/boot/dts中搜索可以看到有stm32mp157a-dk1.dtb和stm32mp157a-dk1.dts两个文件,其中stm32mp157a-dk1.dts为源代码,stm32mp157a-dk1.dtb为编译文件。 ![]() 打开stm32mp157a-dk1.dts可以看到里面只有三aliases、chosen、reserved-memory三个硬件信息,分别是接口、串口波特率和内存。在这里需要加入led的信息: #define PERIPH_BASE (0x40000000) //查阅手册第158页,外设总线地址为AB1-AB5其地址为0x4000 0000 – 0X5FFF FFFF。 #define MPU_AHB4_PERIPH_BASE (PERIPH_BASE + 0x10000000) //查阅手册第158页,gpios总线AHB4,地址为0X50000000 - 0x5001 FFFF。 #define RCC_BASE (MPU_AHB4_PERIPH_BASE+ 0x0000) //查阅手册第162页,gpios时钟,地址为0X50000000-0X5000 0FFFF 。 #define RCC_MP_AHB4ENSETR (RCC_BASE + 0XA28) //查阅手册第866页,RCC_MP_AHB4ENSETR寄存器的偏移地址为0XA28,其负责GPIOA-K的时钟开关 #define GPIOI_BASE (MPU_AHB4_PERIPH_BASE +0x2000) //查阅手册第162页,GPIOA地址为0X5000 2000-0X5000 23FF 。 //接下来是GPIO相关的寄存器,查阅手册第1086页,可以查阅到各个寄存器的偏移地址。 #define GPIOI_MODER (GPIOI_BASE + 0x0000) #define GPIOI_OTYPER (GPIOI_BASE + 0x0004) #define GPIOI_OSPEEDR (GPIOI_BASE + 0x0008) #define GPIOI_PUPDR (GPIOI_BASE + 0x000C) #define GPIOI_BSRR (GPIOI_BASE + 0x0018) 在设备树中添加以上参数: stm32mp1_led { compatible = "stm32mp1-led"; status = "okay"; reg= <0X50000A28 0X04 /* RCC_MP_AHB4ENSETR */ 0X50002000 0X04 /* GPIOI_MODER */ 0X50002004 0X04 /* GPIOI_OTYPER */ 0X50002008 0X04 /* GPIOI_OSPEEDR */ 0X5000200C 0X04 /* GPIOI_PUPDR */ 0X50002018 0X04 >; /* GPIOI_BSRR */ }; 然后重新编译.dtb文件: make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- dtbs 然后将dts/stm32mp157a-dk1.dtb复制到tftp文件夹中: cp arch/arm/boot/dts/stm32mp157a-dk1.dtb /home/helloxhy/tftp/ -rf 接下来写驱动程序: /* 加入设备树所需的头文件 */ #include <linux/of.h> #include <linux/of_address.h> 然后在设备结构体中添加设备节点 : struct newchrled_dev{ dev_t devid; /* 设备号 */ struct cdev cdev; /* cdev */ struct class *class; /* 类 */ struct device *device; /* 设备 */ int major; /* 主设备号 */ int minor; /* 次设备号 */ struct device_node *nd; /* 在设备结构体中添加设备节点 */ }; 最后将led_init中的寄存器直接映射改为在设备树中获取映射地址之后再进行映射: 寄存器映射需要修改为映射设备树中的地址,设备树中为: stm32mp1_led{ compatible= "stm32mp1-led"; status= "okay"; reg= <0X50000A280X04 // RCC_MP_AHB4ENSETR 0X500020000X04 // GPIOI_MODER 0X500020040X04 // GPIOI_OTYPER 0X500020080X04 // GPIOI_OSPEEDR 0X5000200C0X04 // GPIOI_PUPDR 0X500020180X04 >; // GPIOI_BSRR }; 我们需要把设备树中的内容读到设备寄存器中,之前在设备寄存器中特意添加的设备节点信息: structdevice_node *nd; // 在设备结构体中添加设备节点 首先把stm32mp1_led、compatible、status、reg四个参数暂存在*nd。 获取设备树中的属性数据: newchrled.nd =of_find_node_by_path("/stm32mp1_led"); 获取 compatible 属性内容: proper = of_find_property(newchrled.nd,"compatible", NULL); 获取 status 属性内容 ret = of_property_read_string(newchrled.nd,"status", &str); 获取 reg 属性内容 ret =of_property_read_u32_array(newchrled.nd, "reg", regdata, 12); 获取这四个内容后进行映射: MPU_AHB4_PERIPH_RCC_PI= of_iomap(newchrled.nd, 0); GPIOI_MODER_PI= of_iomap(newchrled.nd, 1); GPIOI_OTYPER_PI= of_iomap(newchrled.nd, 2); GPIOI_OSPEEDR_PI= of_iomap(newchrled.nd, 3); GPIOI_PUPDR_PI= of_iomap(newchrled.nd, 4); GPIOI_BSRR_PI= of_iomap(newchrled.nd, 5); 程序的其他内容不变。 ![]() |
基于STM32MP1和STM32MP2在嵌入式Linux平台上部署有效的安全保护机制
利用STM32MP1和STM32MP2为嵌入式Linux提供有效的安全措施:供当今决策者参考的3条宝贵经验
STM32MP1 WiFi连接
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【STM32MPU 安全启动】 TF-A BL2 TrustedBoot原理学习
《STM32MPU安全启动》学**结
《STM32MPU安全启动》学习笔记之optee 如何加载CORTEX-M核和使能校验
《STM32MPU安全启动》学习笔记之TF-A BL2校验optee和uboot的流程以及如何使能
《STM32MPU 安全启动》课程学习心得+开启一扇通往嵌入式系统安全领域深处的大门。
《STM32MPU安全启动》 课程学习心得