目录
2. #address-cells和#size-cells属性
设备树文件类型中,dts是设备树源文件,可以包含其他的dtsi文件,由dtc编译生成dtb文件;
设备树是一个包含节点和属性的简单树状结构;属性就是键值对,而节点可以同时包含属性和子节点;
设备树中有以下几个基本的数据表示形式:
@文本字符串:可以用双引号表示,如string-property="a string";
@32位无符号整型数组信息:用<>限定; 如cell-property=<0x1234 123 0xabc>;
@二进制数据:用[]限定; 如bin-propetry={0x01, 0x23, 0x34, 0x45};
@混合形式:使用逗号分隔; mix-propetry="a string",{0x12,0x23,0x34,0x45},<0x1234354>;
@字符串哈希表:逗号分隔; string-list="sure","cancle";
每个设备都表示一个设备树节点,每个设备树节点都有一个compatible属性; compatible属性是操作系统用来决定使用哪个设备驱动绑定到一个设备上的关键属性;
compatible = "samsung,smdk5250", "samsung,exynos5250";
compatible属性是一个字符串列表,第一个字符串指定了这个节点所表示的确切所表示的设备,该字符串的格式为:"<制造商>,<型号>",其余的字符串则表示其他与之兼容的设备;
#address-cells和#size-cells属性是用来描述子节点的reg信息的;
示例A:
- amba {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "arm,amba-bus";
- ranges;
-
- timer@hisp804 {
- compatible = "hisilicon,hisp804";
-
- reg = <0x12000000 0x20>, /* clocksource */
- <0x12000020 0x20>, /* local timer for each cpu */
- <0x12001000 0x20>;
- ...
-
- };
-
- dual_timer2: dual_timer@12002000 {
- compatible = "arm,sp804", "arm,primecell";
- reg = <0x12002000 0x1000>;
- ...
- };
-
- ...
- };
#address-cells=<1>表示地址需要1个32位整数表示;
#size-cells表示大小需要1个32位的整数表示;
若#address-cells为1,#size-cells为1,那么子节点中每组reg值需要以
为一对;可以有多组;
实例B:
- i2c@12C70000 {
- #address-cells=<1>;
- #size-cells=<0>;
-
- mpu6050@68{
- compatible="xxx, mpu6050";
- reg=<0x68>;
- };
- };
#address-cells值为1,#size-cells值为0;那么reg中每组值只包含address;
#address-cells和 #size-cells与reg的关系也可以说成:一个reg属性需要用到父节点的#address-cells和#size-cell的值;
(1)ranges不为空的情况:
- sysctrl:system-controller@80200{
- compatible = "hisilison,sysctrl";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0,0x802000 0x1000>;
- reg = <0x802000 0x1000>;
-
- clock:clock0@0{
- compatible = "hisilison,hi3620-clock";
- reg = <0,0x10000>;
- #clock-cells = <1>;
- };
- };
clock:clock0@0节点是sysctrl:system-controller@80200的子节点;在父节点中定义了ranges属性,值为一个地址范围,这个地址范围由<子地址 父地址 子地址空间区域大小>这样的元组表示;
所以:<0,0x802000 0x1000>表示子地址0被映射在父地址的0x802000~0x802FFF;
(2)ranges为空的情况:
- apb {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- aic: interrupt-controller@fffff000 {
- #interrupt-cells = <2>;
- compatible = "atmel,at91rm9200-aic";
- interrupt-controller;
- reg = <0xfffff000 0x200>;
- };
- };
表示:子节点aic: interrupt-controller@fffff000 与父节点apb使用一样的地址域;
- media {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "simple-bus";
- interrupt-parent = <&gic>;
- ranges;
-
- ifb: hifb@11440000 {
- compatible = "hisilicon,hisi-hifb";
- reg = <0x11440000 0x40000>, <0x12020000 0x8000>;
- reg-names = "hifb", "sys";
- interrupts = <0 59 4>, <0 51 4>;
- interrupt-names = "hifb", "hifb_soft";
- };
- };
-
interrupt-parent:指向设备所连接的中断控制器;若这个设备节点没有该属性,那将会继承父节点的这个属性; 如上media中断连接到gic中断控制器; 节点ifb: hifb@11440000节点继承父节点的interrupt-parent属性,也连接到gic中断控制器上;
interrupts:对于该设备上的每个中断输出信号; 如上:interrupts = <0 59 4>, <0 51 4>;
第一个表中断类型,0表spi,1表ppi;
第二个为中断号;
第三个表示中断触发类型;1为上升沿触发,2为下降沿触发,4为高电平触发,8为低电平触发;
interrupt-names:中断名字,由字符串表示,多个名字间用逗号相隔;
- gic: interrupt-controller@10300000 {
- compatible = "arm,cortex-a7-gic";
- #interrupt-cells = <3>;
- #address-cells = <0>;
- interrupt-controller;
- /* gic dist base, gic cpu base , no virtual support */
- reg = <0x10301000 0x1000>, <0x10302000 0x100>;
- };
-
- syscounter {
- compatible = "arm,armv7-timer";
- interrupt-parent = <&gic>;
- interrupts = <1 13 0xf08>,
- <1 14 0xf08>;
- clock-frequency = <50000000>;
- };
interrupt-controller:定义该节点是一个接收中断的设备,即是一个中断控制器;
#interrupt-cells:声明了该中断控制器的中断指示符中cell的个数;与#address-cell类似;
aliases节点用于指定节点的别名;应为要引用一个节点要使用全路径,当子节点离根节点较远时,节点名会显得比较冗长,定义一个别名更方便;
- aliases {
- serial0 = &uart0;
-
- i2c0 = &i2c_bus0;
- i2c1 = &i2c_bus1;
- i2c2 = &i2c_bus2;
- i2c3 = &i2c_bus3;
-
- spi0 = &spi_bus0;
- spi1 = &spi_bus1;
- spi2 = &spi_bus2;
-
- gpio0 = &gpio_chip0;
- ...
- };
uart0的全路径为:/soc/amba/uart0: uart@120a0000;serial0可代替该路径;
chosen节点不描述一个真实的设备,而是用于firmware传递一些数据给操作系统;
- chosen {
- bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
- };