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

DTC:编译器
DTS:设备树源文件
DTSI:设备树头文件
DTB:设备树编译所得文件
需进入到Linux内核源码目录
make dtbs # 编译所有设备树
make xxx.dtb # 编译某个设备树
命名格式
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>;};
};
其实就是读取各个节点的信息,并把它们放入到代码变量中,从而实现各个功能配置。
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");
}