设备树源文件(DTS)编码风格

编写设备树源文件(DTS)时,请遵守以下准则。它们应被视为对设备树规范和 dtc 编译器(包括 W=1 和 W=2 构建)中已表达的任何规则的补充。

各个架构和子架构可以定义其他规则,使编码风格更加严格。

命名和有效字符

设备树规范允许在节点和属性名称中使用范围广泛的字符,但此编码风格缩小了范围,以实现更好的代码可读性。

  1. 节点和属性名称只能使用以下字符

    • 小写字符:[a-z]

    • 数字:[0-9]

    • 破折号:-

  2. 标签只能使用以下字符

    • 小写字符:[a-z]

    • 数字:[0-9]

    • 下划线:_

  3. 除非总线另有定义,否则单元地址应使用小写十六进制数字,且不带前导零(填充)。

  4. 属性中的十六进制值(例如“reg”)应使用小写十六进制。地址部分可以使用前导零填充。

示例

gpi_dma2: dma-controller@a00000 {
        compatible = "qcom,sm8550-gpi-dma", "qcom,sm6350-gpi-dma";
        reg = <0x0 0x00a00000 0x0 0x60000>;
}

节点顺序

  1. 任何总线上的节点(因此对其子节点使用单元地址)应按单元地址升序排列。或者,对于某些子架构,可以将相同类型的节点分组在一起,例如,所有 I2C 控制器一个接一个,即使这会破坏单元地址排序。

  2. 没有单元地址的节点应按节点名称的字母数字顺序排序。对于少数节点类型,它们可以按主要属性排序,例如,引脚配置状态按“pins”属性的值排序。

  3. 当通过 &label 扩展板 DTS 中的节点时,条目应按字母数字顺序排序,或者保持来自 DTSI 的顺序,具体选择取决于子架构。

上述排序规则易于在审查期间强制执行,减少同时向文件添加新节点时发生冲突的可能性,并有助于浏览 DTS 源代码。

示例

/* SoC DTSI */

/ {
        cpus {
                /* ... */
        };

        psci {
                /* ... */
        };

        soc@0 {
                dma: dma-controller@10000 {
                        /* ... */
                };

                clk: clock-controller@80000 {
                        /* ... */
                };
        };
};

/* Board DTS - alphabetical order */

&clk {
        /* ... */
};

&dma {
        /* ... */
};

/* Board DTS - alternative order, keep as DTSI */

&dma {
        /* ... */
};

&clk {
        /* ... */
};

设备节点中属性的顺序

首选设备节点中属性的以下顺序

  1. “compatible”

  2. “reg”

  3. “ranges”

  4. 标准/通用属性(由通用绑定定义,例如,没有供应商前缀)

  5. 供应商特定属性

  6. “status”(如果适用)

  7. 子节点,每个节点前都有一个空行

“status”属性默认为“okay”,因此可以省略。

上述排序遵循以下方法

  1. 最重要的属性启动节点:compatible 然后是总线寻址以匹配单元地址。

  2. 每个节点都将在相似的位置具有通用属性。

  3. 状态是注释设备节点是否完成的最后信息(需要板资源)。

示例

/* SoC DTSI */

device_node: device-class@6789abc {
        compatible = "vendor,device";
        reg = <0x0 0x06789abc 0x0 0xa123>;
        ranges = <0x0 0x0 0x06789abc 0x1000>;
        #dma-cells = <1>;
        clocks = <&clock_controller 0>, <&clock_controller 1>;
        clock-names = "bus", "host";
        #address-cells = <1>;
        #size-cells = <1>;
        vendor,custom-property = <2>;
        status = "disabled";

        child_node: child-class@100 {
                reg = <0x100 0x200>;
                /* ... */
        };
};

/* Board DTS */

&device_node {
        vdd-supply = <&board_vreg1>;
        status = "okay";
}

缩进

  1. 根据 Linux 内核编码风格 使用缩进。

  2. 具有多个单元格的数组中的每个条目(例如,具有两个 IO 地址的“reg”)都应括在 <> 中。

  3. 对于跨越多行的数组,首选将连续的条目与第一行的开头 < 对齐。

示例

thermal-sensor@c271000 {
        compatible = "qcom,sm8550-tsens", "qcom,tsens-v2";
        reg = <0x0 0x0c271000 0x0 0x1000>,
              <0x0 0x0c222000 0x0 0x1000>;
};

组织 DTSI 和 DTS

DTSI 和 DTS 文件应以表示硬件的通用、可重用部分的方式组织。通常,这意味着将 DTSI 和 DTS 文件组织到多个文件中

  1. DTSI,包含整个 SoC 的内容,不包含 SoC 上不存在的硬件的节点。

  2. 如果适用:DTSI,包含硬件的通用或可重用部分,例如,整个系统模块。

  3. DTS,表示板。

板上存在的硬件组件应放置在板 DTS 中,而不是 SoC 或 SoM DTSI 中。一个部分例外是常见的外部参考 SoC 输入时钟,它可以在 SoC DTSI 中编码为固定时钟,其频率由每个板 DTS 提供。