设备树就是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) 5 I6 d5 Q7 x/ p, b在设备树中添加以上参数: 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); 程序的其他内容不变。 |
最新消息:意法半导体最具性价比、速度最快的单核MPU STM32MP13现已支持运行RTOS!意法半导体兑现了之前的承诺!
STM32MP135F-DK开发板评测-开箱亮屏
意法半导体扩展STM32Cube开发环境,简化单核STM32MP1裸机软件开发
1月18日有奖直播 | 如何在STM32MP13x上实现FOTA升级?
【STM32MP13x直播回顾】 直播答疑汇总
STM32MP135 开发平台介绍
使用STM32MP13: 如MCU般在Cortex-A核上裸 跑应用程序
米尔核心板加速基于STM32MP1的产品开发
STM32MP1充电桩全数字交互实现
STM32MP13 产品线 应用于工业和安全的高性价比MPU