設備樹的理解
個人理解
設備樹是一種設備信息結構體,在一個嵌入式系統中,存在各種設備,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 = <®_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 = <ðphy0>;
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
屬性值類型:任意數量的 <子地址、父地址、地址長度>編碼