Devicetree 源 (DTS) 編碼風格

編寫 Devicetree 源 (DTS) 時,請遵守以下準則。它們應被視為對 Devicetree 規範和 dtc 編譯器(包括 W=1 和 W=2 構建)中已表達的任何規則的補充。

各個架構和子架構可以定義附加規則,使編碼風格更嚴格。

命名和有效字元

Devicetree 規範允許節點和屬性名稱中使用廣泛的字元,但此編碼風格將範圍縮小以實現更好的程式碼可讀性。

  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. Status 是最後的資訊,用於註釋裝置節點是否已完成(需要板級資源)。

每個組內的各個屬性應按屬性名稱使用自然排序順序。

示例

/* 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-0v9-supply = <&board_vreg1>;
        vdd-1v8-supply = <&board_vreg4>;
        vdd-3v3-supply = <&board_vreg2>;
        vdd-12v-supply = <&board_vreg3>;
        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>;
        /* Lines exceeding coding style line wrap limit: */
        interconnects = <&aggre1_noc MASTER_USB3_0 0 &mc_virt SLAVE_EBI1 0>,
                        <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>;
};

組織 DTSI 和 DTS

DTSI 和 DTS 檔案應以表示硬體的通用、可重用部分的方式組織。通常,這意味著將 DTSI 和 DTS 檔案組織成以下幾個檔案:

  1. 包含整個 SoC 內容的 DTSI,不包含 SoC 上不存在的硬體節點。

  2. 如果適用:包含硬體通用或可重用部分的 DTSI,例如整個系統級模組 (SoM)。

  3. 代表板的 DTS。

板上存在的硬體元件應放置在板級 DTS 中,而不是 SoC 或 SoM DTSI 中。一個部分例外是常見的外部參考 SoC 輸入時鐘,它可以作為固定時鐘編碼在 SoC DTSI 中,其頻率由每個板級 DTS 提供。