参考 :
https://doc.embedfire.com/linux/rk356x/driver/zh/latest/linux_driver/base_dynamic_device_tree.html
https://www.jianshu.com/p/dc2919b140da
: 前的是节点别名; = 前的是属性名; =后的是属性值; { 前的是节点名; < >中既可以10进制数也可以16进制数
初始化platform_device时,根据设备树中设备节点的"compatible"属性和platform_driver中的of_match_table对应的值加载对应的驱动
设备树中的每一个设备的节点都要有一个compatible属性。
设备树节点,“/ {…};”表示“根节点”,每一个设备树只有一个根节点。不同文件的根节点最终会合并为一个。在根节点内部的“chosen{…}”、“leds{…}”等字符,都是根节点的子节点。
设备树节点追加内容,子节点比根节点下的子节点多了一个“&”, 这表示该节点在向已经存在的子节点追加数据。本代码中的“&pwm1{…}”、“&uart1{…}”等等追加的目标节点,就是定义在==“imx6ul.dtsi”==中。
主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。 /proc/devices类似一个类别,而/dev/下是某个类别下的项,由他们两个最终确定了一对多关系。
设备device和驱动driver的区别:设备对应具体的芯片,一个设备有且只能匹配一个驱动程序,但一个驱动程序可以适配若干个设备。
/sys/firmware/devicetree/ 目录下是以目录结构程现的dtb文件, 根节点对应base目录, 每一个节点对应一个目录文件夹, 每一个属性对应一个文件(可以cat)。
节点(node)的格式为:
[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
};
[ 中的内容可有可无 ], label 等用于此node的别名,用&label的形式引用
属性(properties)就是键值对即 “name=value” 的形式,value有3种取值方式
属性格式1有值的形式 [label:] property-name = value;
属性格式2无值的形式 [label:] property-name; 属性也可以用别名&label引用
value值只有3种形式 数字类型 <0x1234>; 字符串类型 "hello"; 数组类型 [0x12 0x7F]
reg 属性只会被其上最近的#address-cells和#size-cells修饰
{ 中有compatible的才会被转为节点/子节点 },满足此要求的才会被转为platform-device,即无compatible的节点不会转为platform-device,compatible属性中不能有空格,必须是连续的字符串;
ls /sys/bus/platform/devices 可以查看设备树中的那些节点被转为platform-device;
ls /proc/device_tree/ 查看设备树中那些节点被成功引入;
plt_dev 和 plt_drv 根据 name 匹配,然后从pltdrv_probe中取plt_dev的属性信息;其匹配优先级顺序为 name < id_table < of_match_table , dts用of_match_table匹配,非dts方式用name和id_table匹配。
(设备节点)device_node != platform_device, 但 platform_device.dev.of_node == device_node
常用属性:#address-cells=; #size-cells=; compatible=; model=; status=; reg=; 这几个都是规范中制定的固定属性名; 可以有用户自定义的属性名比如 asdasd=; 只要自己私有驱动中能有对此属性名的解释即可