Linux驅動系列--4.設備樹

設備樹的理解

個人理解

設備樹是一種設備信息結構體,在一個嵌入式系統中,存在各種設備,CPU,RAM,ROM,IIC,定時器,SPI等等都是一種設備,在系統構建時,爲了方便設備驅動開發,將各種設備的信息以樹狀結構整合到一起,在編寫驅動時,從設備樹上獲取設備基礎信息,進行設備的配置和操作。
在設備樹中根節點爲設備樹的根,設備以樹幹-樹枝-樹葉的結構鏈接,設備信息包含:兼容性,寄存器地址,設備類型等信息。

設備樹的生成

設備樹文件格式爲.dtb格式,有dtsi文件通過dtb編譯器編譯而來。我們通常通過修改dtsi文件,編譯生成設備樹文件。
根據具體電路原理圖及數據手冊修改設備樹文件後,編譯加載設備樹,即可在系統中發現修改後的設備文件,然後在編寫底層驅動時,根據提取設備文件的描述信息,對設備進行初始化和讀寫操作。

設備樹語法

設備樹組成

  • demo
/*--------------------第一部分----------------*/
#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"            ---------------①


/*--------------------第二部分----------------*/
/ {  --------------------②
    model = "Seeed i.MX6 ULL NPi Board";
    compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";

    aliases {
            pwm0 = &pwm1;
            pwm1 = &pwm2;
            pwm2 = &pwm3;
            pwm3 = &pwm4;
    };
    chosen {
            stdout-path = &uart1;
    };

    memory {
            reg = <0x80000000 0x20000000>;
    };

    reserved-memory {
            #address-cells = <1>;
            #size-cells = <1>;
            ranges;

            linux,cma {
                    compatible = "shared-dma-pool";
                    reusable;
                    size = <0x14000000>;
                    linux,cma-default;
            };
    };
    /*-------------以下內容省略=-------------*/
};

/*--------------------第三部分----------------*/
&cpu0 {  --------------------③
    dc-supply = <&reg_gpio_dvfs>;
    clock-frequency = <800000000>;
};

&clks {  --------------------④
    assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <786432000>;
};


&fec1 {  --------------------⑤
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    status = "okay";
};
/*-------------以下內容省略=-------------*/
  • 頭文件
    設備樹可以包含頭文件。經常講一款MPU的設備樹信息寫成一個dts文件,其它板子使用時,只需要包含這個頭文件就把MPU信息加進來了。

  • 根節點
    /{…}中’/'代表根節點,所有信息都是在根節點之下,一個dts文件只能有一個根節點,不同的頭文件中的根節點會合並在一起。

  • 追加節點信息
    &cpu0中爲節點cpu0追加信息。節點可以爲本文件中的子節點,也可以是不同的頭文件包含的子節點。

  • 節點定義

node-name@unit-address{
屬性1 = …
屬性2 = …
屬性13= …
子節點…
}

node-name爲節點名,@爲分隔符,unit-address爲節點reg屬性首地址,若無reg屬性可直接省略@unit-address。同級子節點節點名唯一,節點名相同,unit-address不同也可以。

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

其中cpu0爲節點別名,方便直接通過&cpu0對其追加信息。爲此產生一個特殊節點:別名子節點,作用是爲其他節點定義別名。

aliases {
    can0 = &flexcan1;
    can1 = &flexcan2;
    ethernet0 = &fec1;
    ethernet1 = &fec2;
    gpio0 = &gpio1;
    gpio1 = &gpio2;
    gpio2 = &gpio3;
    gpio3 = &gpio4;
    gpio4 = &gpio5;
    i2c0 = &i2c1;
    i2c1 = &i2c2;
    /*----------- 以下省略------------*/
}
  • choosen 子節點
    不代表實際硬件,用於向內核傳遞參數。

節點屬性

  • compatible
    通常由一個或多個字符串組成,定義了設備編程模型,用於設備和驅動匹配。
intc: interrupt-controller@a01000 {
    compatible = "arm,cortex-a7-gic";
    #interrupt-cells = <3>;
    interrupt-controller;
    reg = <0xa01000 0x1000>,
          <0xa02000 0x100>;
};
  • model
    用於指定設備的製造商和型號,推薦使用“執照商, 型號”的格式。

  • status
    用於指示設備操作狀態,狀態值如下

狀態值 描述
“okay” 設備正常運行
“disabled” 設備目前尚未運行,但是未開可能運行(比如熱插拔)
“fail” 表示設備不可操作
“fail-sss” 設備不可操作,因爲檢測到嚴重錯誤。
  • #address-cells和#size-cells
    二者同時存在,用於設置子節點的“reg”屬性的“書寫格式”。size指定子節點reg屬性地址字段所佔長度。

  • reg
    格式reg = <0x900000 0x4000>,表示起始地址爲0x900000長度爲0x4000的一段空間。

  • ranges
    屬性值類型:任意數量的 <子地址、父地址、地址長度>編碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章