【嵌入式Linux学习笔记】Linux设备树
创始人
2025-05-29 07:48:55

在这里插入图片描述

Linux的设备树将每个外设都视为一个节点,整体架构很明确清晰,也很便于设备管理。

学习视频地址:【正点原子】STM32MP157开发板

1. 设备树结构

在这里插入图片描述

2. 文件关系

DTC:编译器
DTS:设备树源文件
DTSI:设备树头文件
DTB:设备树编译所得文件

编译设备树

需进入到Linux内核源码目录

make dtbs # 编译所有设备树
make xxx.dtb # 编译某个设备树

3. 设备树语法

设备节点

命名格式

node-name@unit-address # unit-address表示设备地址或寄存器首地址
label: node-name@unit-address # label可以便于访问节点

数据形式

compatible = "arm,cortex-a7"; # 字符串
reg = <0 0x123456 100> # 32位无符号整数
compatible = "st,stm32mp157d-atk", "st,stm32mp157"; # 字符串列表

标准属性

compatible:兼容性属性,用于将设备和驱动进行绑定,格式如下,前者为厂商,后者为驱动名字

compatible = "manufacturer,model"

model:描述开发板的名字或者设备模块信息

model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";

status:状态属性
在这里插入图片描述
#address-cells 和#size-cells:长度属性
这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells 属性值决定了子节点 reg 属性中地址信息所占用的字长(32 位),#size-cells 属性值决定了子节点 reg 属性中长度信息所占的字长(32 位)。

reg:寄存器属性

reg = 

ranges:地址映射/转换表
属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字
矩阵,ranges 属性每个项目由子地址、父地址和地址空间长度这三部分组成:

child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells 确定此物理地址 所占用的字长。
parent-bus-address:父总线地址空间的物理地址,同样由父节点的#address-cells 确定此物 理地址所占用的字长。
length:子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。

特殊节点

aliases:定义别名

aliases {serial0 = &uart4;
};

chosen: uboot向Linux内核传递数据,如以下这样子定义属性之后,chosen中会存在bootargs和stdout-path两个属性

chosen {stdout-path = "serial0:115200n8";
};

向节点追加信息

以在i2c节点下添加fxls8471芯片节点为例,我们需要在.dts文件中添加相应的内容,这样子不会影响其他引用了i2c所在的.dtsi文件的设备树

&i2c1 {/* 要追加或修改的内容 */
};
#例
&i2c1 {pinctrl-names = "default", "sleep";pinctrl-0 = <&i2c1_pins_b>;pinctrl-1 = <&i2c1_pins_sleep_b>;status = "okay";clock-frequency = <100000>;fxls8471@1e {compatible = "fsl,fxls8471";reg = <0x1e>;position = <0>;interrupt-parent = <&gpioh>;interrupts = <6 IRQ_TYPE_EDGE_FALLING>;}; 
};

4. 设备树在代码文件中的使用

其实就是读取各个节点的信息,并把它们放入到代码变量中,从而实现各个功能配置。

dtsled.nd = of_find_node_by_path("/stm32mp1_led");
if(dtsled.nd == NULL) {printk("stm32mp1_led node nost find!\r\n");return -EINVAL;
} else {printk("stm32mp1_lcd node find!\r\n");
}/* 2、获取compatible属性内容 */
proper = of_find_property(dtsled.nd, "compatible", NULL);
if(proper == NULL) {printk("compatible property find failed\r\n");
} else {printk("compatible = %s\r\n", (char*)proper->value);
}/* 3、获取status属性内容 */
ret = of_property_read_string(dtsled.nd, "status", &str);
if(ret < 0){printk("status read failed!\r\n");
} else {printk("status = %s\r\n",str);
}/* 4、获取reg属性内容 */
ret = of_property_read_u32_array(dtsled.nd, "reg", regdata, 12);
if(ret < 0) {printk("reg property read failed!\r\n");
} else {u8 i = 0;printk("reg data:\r\n");for(i = 0; i < 12; i++)printk("%#X ", regdata[i]);printk("\r\n");
}

相关内容

热门资讯

掌上生财APP虚假交易平台骗人...   掌上生财APP本身就是一虚假交易平台,宣传做这个现货订购能赚钱,充值还送现等活动,其实就是让客户...
中国白银APP虚拟盘交易骗局,...   中国白银APP商城订购存在虚拟盘交易,并非是实盘在交易!平台修改参数,指数走势完全不对,其中包含...
起点订购交易平台非法期货,贵金...   在起点订购APP做交易的受害者很多,投诉无门!还有很多投资者根本不知道自己遭遇了一场骗局!现在互...
全新易购APP欺骗消费者,利用...   不要“充值送现”、“首单免赔”等广告给迷惑,这些宣传标语只是一个宣传语,诱导普通大众去参与投资,...
大吉订购、兴鑫淘金APP现货订...   大吉订购APP投资人亏损的资金能追回?该平台是否有期货经营资质?为什么一个现货订购平台能做高杠杆...