在.dts文件中对设备及其属性的描述通常如以下这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43/ { compatible = "acme, coyotes-revenge"; #address-cells = <1>; #size-cells = <1>; ... cpus { #address-cells = <1>; #size-cells = <0>; cpu@0 { compatible = "arm, cortex-a9"; reg = <0>; }; cpu@1 { compatible = "arm, cortex-a9"; reg = <1>; }; }; serial1@101f0000 { compatible = "arm,pl1011"; reg = <0x101f0000 0x1000>; interrupts = < 1 0 >; }; ... external-bus { #address-cells = <2>; #size-cells = <1>; ranges = <0 0 0x10100000 0x1000 // ChipSelect 1, Ethernet 1 0 0x10160000 0x1000 // ChipSelect 2, i2c controller 2 0 0x30000000 0x100000>; // ChipSelect 3, NOR Flash ethernet@0,0 { compatible = "smc,smc91c111"; reg = <0 0 0x1000> interrupts = < 5 2 >; }; ... }; };
其中compatible代表设备节点的兼容属性(略);
reg代表地址编码,reg组织形式为:
reg = <address1 length1 [address2 length2] [address3 length3] ... >
以上的每组 “address length” 表征了设备使用的一个地址范围。
address为1个或者多个32-bit的整型(即cell);
length的含义是从 address 到 address + length - 1 的地址范围都属于该设备节点;
(一)地址编码
前述 address 和 length 字段是可变长度的,父节点的 #address-cells 和 #size-cells 分别决定了子节点reg属性的 address 字段的个数和 length 字段的个数。
若#size-cells = <0>,则表示length字段为空。
在上述.dts文件描述中,root节点的:#address-cells = <1>; #size-cells = <1>; 意味着root节点下面的各个子节点的 address字段和 length字段的个数分别为1。例如,serial1这个子节点:
reg = <0x101f0000 0x1000>
它就是符合:address字段的个数为1,length字段的个数为1。
而 cpus 这个子节点它又包含了子节点,并且 cpus 的 reg 属性是:#address-cells = <1>; #size-cells = <0>; 所以 cpus 的子节点 cpu 的reg属性为:
reg = <0>
或者 reg = <1>
即 length 字段为空。
接着,再看 root 节点的 external-bus 子节点:
external-bus {
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0x10100000 0x1000 // ChipSelect 1, Ethernet
1 0 0x10160000 0x1000 // ChipSelect 2, i2c controller
2 0 0x30000000 0x100000>; // ChipSelect 3, NOR Flashethernet@0,0 {
compatible = "smc,smc91c111";
reg = <0 0 0x1000>
interrupts = < 5 2 >;
};
...
};
它代表 address 字段的个数为2,而 length 字段的个数为1。意味着其下的 ethernet 子节点的 reg 属性形如:
reg = <0 0 0x1000>;
值得说明的是,通常 root 节点的直接子节点的 address 区域就直接位于 CPU 的内存区域,而经过总线桥以后的 address 往往需要经过转换才能对应到 CPU 的内存映射区域。
在以上 external-bus 节点的描述中,ranges 表示地址转换表。
ranges 中的每个项目是:子 address + 父 address (子 address 的地址映射)及映射的大小。
具体而言,external-bus 这个子节点的 #address-cells 值为2,而其父节点(root 节点)的 #address-cells 值为1,所以 ranges 中:
0 0 0x10100000 0x1000
前面两个cell (即 0 0 )代表总线桥上面片选 0 和 偏移地址 0;
第3个cell (即 0x10100000 )代表总线桥上面片选 0 和 偏移地址 0 的地址空间被映射到了 CPU 本地总线的 0x10100000 位置,也就是所谓的 “父 address” ;
第4个cell(即 0x1000 )代表地址空间映射的大小为 0x1000 。
(二)中断控制器节点
1
2
3
4
5
6intc: interrupt-controller@10140000 { compatible = "arm,pl190"; reg = <0x10140000 0x1000>; interrupt-controller; #interrupt-cells = <2>; };
上述 #interrupt-cells 与 #address-cells 和 #size-cells 相似,它表示连接到此中断控制器的设备的中断属性的 cell 个数。
在整个设备树中,与中断相关的属性还有:
1)interrput-parent属性
设备节点通过它来指定它所依附的中断控制器的phandle,当设备节点没有指定 interrupt-parent 属性之时,则从父级节点继承。
2)interrupts属性
设备节点通过它指定中断号、触发方法等,这个属性具体包含多少个 cell,由它依附的中断控制器节点的 #interrupt-cells 属性决定。而每个 cell 具体又是什么含义,一般由驱动的实现决定,而且也会在设备树的绑定文档中进行说明。
(三)GPIO控制器节点
对于GPIO控制器而言,其对应的设备需声明 gpio-controller 属性,并设置 #gpio-cell 的个数。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22pinctrl@80018000 { compatible = "fsl,imx28-pinctrl","simple-bus"; reg = <0x80018000 2000>; gpio0: gpio@0 { compatible = "fsl,imx28-gpio"; interrupts = <127>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; gpio1: gpio@0 { compatible = "fsl,imx28-gpio"; interrupts = <126>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; };
其中,#gpio-cells 为2,第一个 cell 为 GPIO 号,第二个 cell 为 GPIO 的极性:为0的时候是高电平有效,为1的时候是低电平有效。
使用GPIO的其他设备可以通过定义 xxx-gpios 属性来引用 GPIO 控制器设备节点,例如:
1
2
3
4
5
6
7sdhci@c8000400 { status = "okay"; cd-gpios = <&gpio01 0>; wp-gpios = <&gpio02 0>; power-gpios = <&gpio03 0>; bus-width = <4>; };
而具体的设备驱动则通过以下方法来获取GPIO:
1
2
3cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); power_gpio = of_get_named_gpio(np, "power-gpios", 0);
of_get_named_gpio这个API的原型如下:
1
2
3static inline int of_get_named_gpio( struct device_node *np, const char *propname, int index );
最后
以上就是自由香烟最近收集整理的关于ARM Linux设备树(3)的全部内容,更多相关ARM内容请搜索靠谱客的其他文章。
发表评论 取消回复