Linux设备树

扫盲知识

DTS:设备树源文件

DTSI:设备树头文件(.dts 文件引用 C 语言中的.h 文件,甚至也可以引用.dts 文 件)

DTC:编译设备树的工具

DTB:设备树被编译之后的二进制文件

如果要编译 DTS 文件的话只需要进入到 Linux 源码根目录下,然后执行如下命 令:
make all   或者: make dtbs。
当选中 I.MX6ULL 这个 SOC 以后 (CONFIG_SOC_IMX6ULL=y) ,所有使用到
I.MX6ULL 这个 SOC 的板子对应的 .dts 文件都会被编译为 .dtb

设备树语法

1 / {
2     compatible = "fsl,imx6ull-alientek-evk" , "fsl,imx6ull" ;//厂商,板子名称(会和内核匹配是否对应得上)
3 }
cpu0 : cpu@0 {// @cpu0相当于@cpu,cpu0是标签,cpu是节点名称
10     compatible = "arm,cortex-a7" ;
11     device_type = "cpu" ;
12     reg = < 0 >;
13 };
范例:
1 / {
2     compatible = "fsl,imx6ull-alientek-evk", "fsl,imx6ull";
3 
4     cpus {
5         #address-cells = <1>;
6         #size-cells = <0>;
7
8         //CPU0 节点
9         cpu0: cpu@0 {
10             compatible = "arm,cortex-a7";
11             device_type = "cpu";
12             reg = <0>;
13         };
14     };
15 
16     //soc 节点
17     soc {
18         #address-cells = <1>;
19         #size-cells = <1>;
20         compatible = "simple-bus";
21         ranges;
22 
23         //ocram 节点
24         ocram: sram@00900000 {
25             compatible = "fsl,lpm-sram";
26             reg = <0x00900000 0x20000>;//起始地址,大小
27         };
29         //aips1 节点
30         aips1: aips-bus@02000000 {
31             compatible = "fsl,aips-bus", "simple-bus";
32             #address-cells = <1>;
33             #size-cells = <1>;
34             reg = <0x02000000 0x100000>;
35             ranges;

37             //ecspi1 节点
38             ecspi1: ecspi@02008000 {
39                 #address-cells = <1>;
40                 #size-cells = <0>;
41                 compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
42                 reg = <0x02008000 0x4000>;
43                 status = "disabled";
44             };
36         }

38         //aips2 节点
39         aips2: aips-bus@02100000 {
40             compatible = "fsl,aips-bus", "simple-bus";
41             #address-cells = <1>;
42             #size-cells = <1>;
43             reg = <0x02100000 0x100000>;
44             ranges;

               //usbotg1 节点
56             usbotg1: usb@02184000 {
57                 compatible = "fsl,imx6ul-usb", "fsl,imx27-usb";
58                 reg = <0x02184000 0x4000>;
59                 status = "disabled";
                };
45         }
46 
47         //aips3 节点 
48         aips3: aips-bus@02200000 {
49             compatible = "fsl,aips-bus", "simple-bus";
50             #address-cells = <1>;
51             #size-cells = <1>;
52             reg = <0x02200000 0x100000>;
53             ranges;

71             //rngb 节点
72             rngb: rngb@02284000 {
73                 compatible = "fsl,imx6sl-rng", "fsl,imx-rng", "imxrng";
74                 reg = <0x02284000 0x4000>;
75             };
54         }
55    }
29 }

设备树在系统中的体现

Linux 内核启动的时候会解析设备树中各个节点的信息,并且在根文件系统的 /proc/device
tree 目录下根据节点名字创建不同文件夹
使用cat命令查看model和compatible内容,正是设备树文件根节点的对应属性值。
进一步查看子节点里面的节点

特殊节点

aliases 子节点

18 aliases {
19     can0 = &flexcan1;
20     can1 = &flexcan2;
21     ethernet0 = &fec1;
22     ethernet1 = &fec2;
23     gpio0 = &gpio1;
24     gpio1 = &gpio2;
        ......
42     spi0 = &ecspi1;
43     spi1 = &ecspi2;
44     spi2 = &ecspi3;
45     spi3 = &ecspi4;
46     usbphy0 = &usbphy1;
47     usbphy1 = &usbphy2;
48 };
aliases 节点的主要功能就是定义别名。

chosen节点

1 chosen {
2     stdout - path = & uart1 ;
};
chosen 节点仅仅设置了属性“ stdout-path ”,表示标准输 出使用 uart1 。但是当我们进入到 /proc/device-tree/chosen 目录里面,会发现多了 bootargs 这个 属性,如图:
进一步查看bootargs这个属性的值:
这个属性的值和uboot里面设置的bootargs一样。
chosen节点是uboot添加的。

Linux 内核解析 DTB 文件

绑定信息文档

在设备树中添加一个硬件对应的节点的时候从如下路径查找对应稳定说明:
Linux 源码目录/Documentation/devicetree/bindings

设备树常用 OF 操作函数

查找节点的 OF 函数
struct device_node *of_find_node_by_name(struct device_node *from, const char *name);
from :开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树。
name :要查找的节点名字。
返回值: 找到的节点,如果为 NULL 表示查找失败。
struct device_node *of_find_node_by_type(struct device_node *from, const char *type);
函数参数和返回值含义如下:
from :开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树。
type :要查找的节点对应的 type 字符串,也就是 device_type 属性值。
返回值: 找到的节点,如果为 NULL 表示查找失败。
struct device_node *of_find_compatible_node(struct device_node *from,
    const char *type, const char *compatible)
from :开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树。
type :要查找的节点对应的 type 字符串,也就是 device_type 属性值,可以为 NULL ,表示
忽略掉 device_type 属性。
compatible 要查找的节点所对应的 compatible 属性列表。
返回值: 找到的节点,如果为 NULL 表示查找失败
struct device_node *of_find_matching_node_and_match(struct device_node
    *from, const struct of_device_id *matches, const struct of_device_id **match);
from :开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树。
matches of_device_id 匹配表,也就是在此匹配表里面查找节点。
match 找到的匹配的 of_device_id
inline struct device_node *of_find_node_by_path(const char *path);
path :带有全路径的节点名,可以使用节点的别名,比如“ /backlight ”就是 backlight 这个
节点的全路径。
返回值: 找到的节点,如果为 NULL 表示查找失败
查找父/子节点的 OF 函数
struct device_node *of_get_parent(const struct device_node *node)
node :要查找的父节点的节点。
struct device_node *of_get_next_child(const struct device_node *node,  struct device_node     *prev)
node :父节点。
prev :前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为
NULL ,表示从第一个子节点开始。
返回值: 找到的下一个子节点。
提取属性值的 OF 函数
property *of_find_property(const struct device_node *np, const char *name, int *lenp);
np
设备节点。
name : 属性名字。
lenp :属性值的字节数
返回值: 找到的属性。
int of_property_count_elems_of_size(const struct device_node *np,
    const char *propname,intelem_size);
np :设备节点。
proname : 需要统计元素数量的属性名字。
elem_size :元素长度。
返回值: 得到的属性元素数量。
int of_property_read_u32_index(const struct device_node *np, const char *propname,
    u32 index, u32 *out_value);
np :设备节点。
proname : 要读取的属性名字。
index :要读取的值标号。
out_value :读取到的值
返回值: 0 读取成功,负值,读取失败, -EINVAL 表示属性不存在, -ENODATA 表示没有
要读取的数据, -EOVERFLOW 表示属性值列表太小。
...
  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值