接前一篇文章:嵌入式Linux驱动开发指南 —— 设备树语法与编译工具 —— 读懂这张“藏宝图“(1)

节点语法:树的枝干

设备树的核心结构就是。每个设备都是一个节点,每个节点里是一堆键值对,我们称之为属性

节点命名规则

节点的命名格式通常如下:

node-name@unit-address
  • node-name:节点名字,ASCII字符串,比如uart1i2c0
  • unit-address:设备的寄存器首地址,可省略。

实际文件中,我们经常看到带标签的写法:

cpu0: cpu@0
intc: interrupt-controller@00a01000

格式是label: node-name@unit-address。冒号前面的cpu0intc节点标签,方便后面通过&label引用,不用每次敲那长长的一串名字。

我们来看一个从I.MX6ULL设备树截取的完整例子:

/ {
    aliases {
        can0 = &flexcan1;
    };

    cpus {
        #address-cells = <1>;
        #size-cells = <0>;

        cpu0: cpu@0 {
            compatible = "arm,cortex-a7";
            device_type = "cpu";
            reg = <0>;
        };
    };

    intc: interrupt-controller@00a01000 {
        compatible = "arm,cortex-a7-gic";
        reg = <0x00a01000 0x1000>;
        interrupt-controller;
        #interrupt-cells = <2>;
    };
}

几个关键点:

  • 根节点 /:整个树的起点,所有其它节点都是它的子孙。
  • 节点嵌套cpus是根节点的子节点,cpu@0又是cpus的子节点,反映了硬件的层级结构。
  • 标签的使用cpu0intc是标签,可以在文件其它地方通过&cpu0&intc引用。

节点引用:&label机制

这是设备树中最实用的语法糖。假设imx6ull.dtsi里定义了:

i2c1: i2c@021a0000 {
    compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
    reg = <0x021a0000 0x4000>;
    status = "disabled";
};

你想启用I2C1并挂两个设备,只需要在 .dts 里写:

&i2c1 {
    clock-frequency = <100000>;
    status = "okay";

    mag3110@0e {
        compatible = "fsl,mag3110";
        reg = <0x0e>;
    };

    fxls8471@1e {
        compatible = "fsl,fxls8471";
        reg = <0x1e>;
    };
};

既启用了控制器,又挂上了从设备,而且不会污染原始.dtsi。这种“通过引用标签来追加内容”的机制,是设备树移植中最常用的操作。

属性类型:数据的各种面孔

节点里面全是属性,属性就是键值对。DTS支持的数据类型非常直观。

字符串属性

model = "Freescale i.MX6 ULL 14x14 EVK Board";
status = "okay";
device_type = "cpu";

字符串列表用逗号分隔,非常关键 —— 它表示“先试着找前一个驱动,找不到就找后一个”:

compatible = "fsl,imx6ull-gpmi-nand", "fsl,imx6ul-gpmi-nand";

数值属性

数值用尖括号<>包裹,默认是32位无符号整数,支持十进制和十六进制:

reg = <0x02020000 0x4000>;

前一个是地址,后一个是长度(16KB)。

引用属性(phandle)

一个节点需要引用另一个节点时,用&label

gpio1: gpio@0209c000 {
    #gpio-cells = <2>;
    gpio-controller;
};

some-device {
    gpios = <&gpio1 12 0>;
};

编译后的DTB里,&gpio1会被替换为该节点的唯一数字ID(phandle)。

空属性

有些属性不需要值,它们的存在本身就表示某种含义:

gpio-controller;
interrupt-controller;

更多内容请看下回。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐