设备树语法
- 设备树源码文件扩展名为.dts。
- 其他设备树文件引用的描述SOC信息(也就是 SOC 有几个 CPU、主频是多少、各个外设控制器信息等)的文件.dtsi 。
- 源码编译后的文件扩展名为 .dtb。
- 编译工具为DTC。
设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是键—值对。
示例展示
/ { //根节点,每个设备数文件都只有一个根节点。
#address-cells = <1>;
#size-cells = <1>;
aliases { //根节点的子节点
serial0 = &uart4;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
clocks = <&scmi0_clk CK_SCMI0_MPU>;
clock-names = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
nvmem-cells = <&part_number_otp>;
nvmem-cell-names = "part_number";
#cooling-cells = <2>;
};
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
ranges;
sram: sram@10000000 {
compatible = "mmio-sram";
reg = <0x10000000 0x60000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x10000000 0x60000>;
};
};
};
节点命名
节点命名为:
labe:node-name@unit-address
//sram: sram@10000000
- node-name:节点名称,为 ASCII 字符串,节点名字应该能够清晰的描述出节点的功能。
- unit-address:设备映射地址或者寄存器首地址,若没有地址或者寄存器,则可以不用写。
- labe:节点标签,可以直接通过
&labe
快速访问节点。
通过
&sram
来访问sram@10000000
节点。
数据形式
-
字符串:
compatible = "arm,cortex-a7";
。 -
32 位无符号整数,可以是一个数值,也可以是一组数值,
reg = <0 0x123456 100>;
。 -
字符串列表,字符串和字符串之间采用“,”隔开,
compatible = "st,stm32mp157d-atk", "st,stm32mp157";
。
标准属性
节点描述一个设备,而不同的设备拥有不同的属性,很多属性都具有标准属性,用户也可以自定义属性。
compatible 属性
-
“兼容性”属性,用于将设备和驱动结合起来。
-
属性的值是一个字符串列表,字符串列表用于选择设备所要使用的驱动程序。
-
属性的值格式如下所示:
“manufacturer,model” 厂商,驱动名字。
当驱动被使用时,会匹配驱动OF匹配列表与设备树节点compatible的属性,如果匹配,驱动就所引导驱动所操作的设备。
const struct of_device_id cs42l51_of_match[] = {
//设备匹配的数据结构,数组cs42l51_of_match[]里面存放of_device_id的结构体。
{ .compatible = "cirrus,cs42l51", },
//兼容性匹配选型,.compatible指向匹配设备的兼容属性。
{ }
//一个空项目,用于标志匹配的结束。
};
当设备树被解析时,内核会尝试将设备树中的设备与这些匹配项进行匹配,从而找到与此设备相匹配的驱动程序。
可以理解为,一种双向奔赴。
model 属性
- 属性描述开发板的名字或者设备模块信息。
- 属性值是一个字符串。
status 属性
- 属性是用来描述设备状态的。
- 属性值是字符串,表示当前设备的状态。
- 状态选择:
- “okay”:设备是可操作的
- “disabled”:设备当前是不可操作的
- “fail”:设备检测到了一系列的错误
- “fail-sss”:后面的 sss 部分是检测到的错误内容
address-cells 和#size-cells 属性
- #address-cells 属性值决定了子节点 reg 属性中地址信息所占用的字长,以32位为单位。
- size-cells 属性值决定了子节点 reg 属性中长度信息所占的字长,以32位为单位。
- 属性的值都是无符号 32 位整形。
reg 属性
-
属性用于描述设备地址信息或者地址空间资源信息。比如某个外设的寄存器地址范围信息。
-
reg 属性的格式为:
reg =
ranges 属性
- 是一个地址映射/转换表。
- 属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字矩阵。
- 值为空,则子地址空间和父地址空间完全相同。
cpu {
...
bus {
#address-cells = <1>;
#size-cells = <1>;
external-device {
compatible = "external-device";
reg = <0x10000000 0x1000>; // 设备的寄存器地址
memory {
device-type = "memory";
reg = <0x20000000 0x1000>; // 设备内存地址
ranges = <0x20000000 0x10000000 0x1000>; // 子-bus 地址 父-bus 地址 大小
};
};
};
};