设备树语法简介

(1) 语法:

Devicetree node格式:

[label:] node-name[@unit-address] {

[properties definitions](属性定义)

[child nodes](子节点)

};

label: 用于其他节点引用该节点

node-name:节点名

unit-address:由于同一级别下的子节点名称不能相同,可以使用unit-address对名字进行修饰来区分两个类似的节点。

 

Property格式1:

[label:] property-name = value;
 

Property格式2(没有值):

[label:] property-name;

 

Property取值只有3种:

<>修饰的内容为arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示,)

""修饰的内容为string(字符串 )

[]修饰的内容为bytestring(16进制表示1个或多个字节,一个byte用2位16进制数来表示,不可省略数字,byte之间的空格可省略)

 

示例:

a. Arrays of cells : cell就是一个32位的数据

interrupts = <17 0xc>;

b. 64bit数据使用2个cell来表示: 高字节在前

clock-frequency = <0x00000001 0x00000000>;

c. A null-terminated string (有结束符的字符串):

compatible = "simple-bus";

d. A bytestring(字节序列) :

local-mac-address = [00 00 12 34 56 78]; // 每个byte使用2个16进制数来表示

local-mac-address = [000012345678]; // 每个byte使用2个16进制数来表示

e. 可以是各种值的组合, 用逗号隔开:

compatible = "ns16550", "ns8250";

example = <0xf00f0000 19>, "a strange property format";

 

(2) DTS文件布局(layout):

/dts-v1/;



[memory reservations]

// 格式为: /memreserve/ <address> <length>;

//保留从address开始的长度为length的内存不让内核访问



/ {

[property definitions]

[child nodes]

};

 

(3) 特殊的、默认的属性:

a. 根节点:

#address-cells: 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)

#size-cells:在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)

compatible:定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备,即这个板子兼容哪些平台。

假设编译好的uImage支持smdk2410 smdk2440 mini2440等单板,我们就可以通过compatible制定使用哪个单板。

model:具体是哪一个板子,比如有2款板子配置基本一致, 它们的compatible是一样的,那么就通过model来分辨这2款板子

 

例如:

model = "SMDK24440"; //板子的具体型号

compatible = "samsung,smdk2440"; //支持三星公司的smdk2440



#address-cells = <1>;

#size-cells = <1>;

b. /memory

device_type = "memory";

reg // 用来指定内存的地址、大小

 

例如:

memory {
		device_type = "memory";
		reg = <0x30000000 0x4000000 0 0x4096>;
	};

第一块内存起始地址0x30000000 大小0x4000000

第二块内存起始地址0 大小4096

 

c. /chosen

bootargs // 内核command line参数, 跟u-boot中设置的bootargs作用一样

 

例如:

chosen {

bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";

};

 

 

d. /cpus

/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu

所以 /cpus 中有以下2个属性:

#address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)

#size-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)

 

e. /cpus/cpu*

device_type = "cpu";

reg // 表明自己是哪一个cpu

 

(4) 引用其他节点:

a. phandle : // 节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)

pic@10000000 {

phandle = <1>;

interrupt-controller;

};



another-device-node {

interrupt-parent = <1>; //interrupt-parent引用phandle为1的节点

// 使用phandle值为1来引用上述节点

};

 

b. label:

PIC: pic@10000000 {

interrupt-controller;

};



another-device-node {

interrupt-parent = <&PIC>; // 使用label来引用上述节点,

// 使用lable时实际上也是使用phandle来引用,

// 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性

};

 

(5)特殊用法简介

dts文件可包含dtsi文件,dts中如果重复定义了dtsi中的节点会覆盖dtsi中的值。

例如有一个dtsi文件如下,文件名为jz2440.dtsi

// SPDX-License-Identifier: GPL-2.0
/*
 * SAMSUNG SMDK2440 board device tree source
 *
 * Copyright (c) 2018 weidongshan@qq.com
 * dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
 */
 
#define S3C2410_GPA(_nr)	((0<<16) + (_nr))
#define S3C2410_GPB(_nr)	((1<<16) + (_nr))
#define S3C2410_GPC(_nr)	((2<<16) + (_nr))
#define S3C2410_GPD(_nr)	((3<<16) + (_nr))
#define S3C2410_GPE(_nr)	((4<<16) + (_nr))
#define S3C2410_GPF(_nr)	((5<<16) + (_nr))
#define S3C2410_GPG(_nr)	((6<<16) + (_nr))
#define S3C2410_GPH(_nr)	((7<<16) + (_nr))
#define S3C2410_GPJ(_nr)	((8<<16) + (_nr))
#define S3C2410_GPK(_nr)	((9<<16) + (_nr))
#define S3C2410_GPL(_nr)	((10<<16) + (_nr))
#define S3C2410_GPM(_nr)	((11<<16) + (_nr))

/dts-v1/;

/ {
	model = "SMDK24440";
	compatible = "samsung,smdk2440";

	#address-cells = <1>;
	#size-cells = <1>;
		
	memory {  /* /memory */
		device_type = "memory";
		reg =  <0x30000000 0x4000000 0 4096>;		
	};
	
/*
	cpus {
		cpu {
			compatible = "arm,arm926ej-s";
		};
	};
*/	
	chosen {
		bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
	};

	
	led {
		compatible = "jz2440_led";
		pin = <S3C2410_GPF(5)>;
	};
};

1)使用phandle

/dts-v1/;

#include "jz2440.dtsi" //包含dtsi文件
/{
    led{
      pin = <S3C2410_GPF(6)>  ; //重定义led节点中的pin值       
    };
    
}

编译之后pin最终会等于S3C2410_GPF(6)。

 

2)使用label

增加dtsi led节点的label为LED

LED:led {
		compatible = "jz2440_led";
		pin = <S3C2410_GPF(5)>;
	};

在dts文件引用LED,然后修改pin的值

/dts-v1/;

#include "jz2440.dtsi"
&LED{
    pin = <S3C2410_GPF(6)> ; 
}

效果和第一个相同。

 

官方文档:

https://www.devicetree.org/specifications/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值