zynq基礎-->LINUX 設備樹


1.概念

linux設備樹是用於描述硬件及部分啟動指令的文件,由bootloader傳遞給內核(U-boot需要在config文件中加入"#define CONFIG_OF_LIBFDT"),

內核分析此文件而對硬件使用不同的參數。

比如兩塊開發板僅僅是內存容量不一樣,那么就只需要修改設備樹中對內存容量的描述即可,

而不需要重新編譯內核。

與設備樹相關的文件有如下幾種:

DTS(device tree source)

.dts文件,就是ASCII字符串形式的文本文件,直接由開發人員修改。

對於ARM架構而言,這些文件位於:arch/arm/boot/dts 目錄下。

DTSI(device tree source include)

.dtsi文件,用於被.dts文件所包含。並且.dtsi文件也可以包含.dtsi文件。與c/c++ 包含頭文件一個道理。

此文件包含了很多設備下所共有的許多配置。

在.dts文件下,使用"#include "file.dtsi"" 或"/include/ "file.dtsi""來包含。

DTB(device tree blob)

通過工具提前將DTS文件編譯為.dtb二進制文件,bootloader傳遞此文件給內核,這樣內核的解析速度才快。

DTC(device tree compiler)

將.dts文件編譯為.dtb的工具,其源碼位於scripts/dtc目錄下,此工具根據用戶設定的SOC來確定編譯哪種目標板。

Binding

對於設備樹中的節點及屬性具體描述文檔,位於Document/devicetree/bindings,、

需要仔細閱讀!需要仔細閱讀!需要仔細閱讀!

2.規則

 設備樹的結構是由節點和節點中的屬性構成的,這就如同c/c++中結構體名稱和元素名稱及元素值的關系一樣。

#include "skelston.dtsi" /*包含*/
/{
    node{
    a-string-property = "string";
    };
};

/*
 "/" 代表根節點,根節點是設備樹的起始節點,一個設備文件中必須且僅有一個根節點,"node"是一個子節點名,
"a-string-property"是一個屬性名,"string"是屬性值。
*/

2.1 節點

2.1.1節點命名及路徑

節點命名可以有如下幾種方式:

1、以"設備名"為節點名

比如設備DM9000,對應的節點路徑為:/dm9000

/{
...
dm9000{
...
};
...
};

2、以"設備名@I/O地址"為節點名:

比如設備DM9000位於I/O地址為0x8000 0000,對應的節點路徑為:/dm9000@80000000

注意:這種方式下,若兩個節點具有相同的設備名和不同的I/O地址,也同樣代表兩個不同的設備

/{
...
dm9000@80000000{
...
};
...
};

2.1.2節點引用

如同linux中可以為命令命名別名(alias)一樣,節點也可以先命名別名再引用。

注意:在節點引用的同時,其內容等同於被引用過來了。

/{
...
dm9000:dm9000@80000000{
...
};
...

&dm9000{

};
};
/*
&dm9000就等價於 dm9000@80000000
*/

2.1.3節點合並

若同一設備樹中有相同的節點名及地址時,節點的內容會合並。

若節點內容中出現了相同的屬性,則新屬性值替換掉老的屬性值

比如在petalinux中可以修改頂層的設備樹文件,將新的設置信息與老的合並或替換。而不用關心以前默認的設定值。

2.2屬性

2.2.1屬性的內容

屬性的內容比較靈活,可以為:

1、空(比如:an-empty-proerty;)

2、字符串(比如:a-string-property = "A string";)

3、字符串數組(比如:a-string-list-property = "first string","second string";)

4、整數(比如:a-cell-property = <1234>;)

5、16進制數(比如:a-byte-data-property = [0x01 0x02 0x03 0x04];)

2.2.2常用的屬性名及內容的意義

有關屬性名及內容更為具體的意義和使用方式,需要仔細反復閱讀Documentation/devicetree/目錄下的相關文件!

下面列出一些常用的屬性:

1、compatible(兼容)

compatible的內容為字符串數組,其形式為:<manufacturer>,<model>。

其意義代表設備"廠商和哪個具體的型號"或者"具體設備名稱和兼容設備",linux內核中的解析代碼,通過節點此屬性來確定這個具體的驅動匹配

比如在zynq-7000.dtsi中根節點屬性:

compatible = "xlnx,zynq-7000"

在zynq-zed.dts中qspi結點中flash子節點的屬性:

/{
...
&qspi{
...
    flash@0{
     compatible = "n25q128a11";
    ...
    }

};
...
};

2、reg(設備地址)

reg的內容一般為16進制數,其形式為:<address 1 length 1 [address 2 length 2] [address 3 length 3] ...>,

address代表此設備相對於父節點的偏移地址

length代表設備可以操作的地址范圍,也就是地址大小

reg中的address和length數量的多少,是由#address-cells和#size-cells兩個屬性來決定子節點的reg內容

比如:

在zynq-70000.dtsi文件中 cpus節點定義#address-cells = 1,#size-cells=0,代表子節點的reg屬性中地址1位,大小位為空。

/{
...
    cpus{
        #address-cells = <1>;
        #size-cells = <0>;
        cpu@0{
            ....
            reg = <0>;
            ....
       }; 
       cpu@1{
           ....
           reg = <1>;
           ....
       };
    };
};

 

在ambs節點中定義#address-cells = 1,#size-cells = 1,代表子節點reg屬性中地址和大小都為1位。

/{
    amba:amba{
    ....
    #address-cells = <1>;
    #size-cells = <1>;
     ....
     adc:adc@f8007100{
    ....
    reg = <0xf8007100 0x20>;
    ....
    };
    gpio0:gpio@e000a000{
    ...
    reg = <0xe000a000 0x1000>;
    ...
    };
    };
};

 

3、interrupt-controller(中斷控制器)

此屬性為空,通過此屬性以表明此設備具有中斷相關功能。

4、#interrupt-cells(表明interrupts屬性中地址大小)

與#size-cells相似

5、interrupt-parent(指明此控制器所依附的中斷控制器)

若子節點中沒有指明此屬性,則從父節點中繼承。

比如zynq-70000.dtsi中的gpio控制器節點:

/{
....
    gpio0:gpio@e00a000{
    compatible = "xlnx,zynq-gpio-1.0";
    #gpio-cells = <2>;
    #interrupt-cells = <2>;
    clocks = <&clkc 42>;
    gpio-controller;
    interrupt-controller;
    interrupt-parent = <&intc>;
    interrupts = <0 20 4>;
    reg = <0xe00a000 0x1000>;
    };
....
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM