这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » Zynq基础 5:LINUX 设备树

共2条 1/1 1 跳转至

Zynq基础 5:LINUX 设备树

菜鸟
2017-06-28 16:35:33     打赏
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>;
    };
....
};


专家
2017-06-29 08:16:13     打赏
2楼
谢谢楼主分享。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]