設備樹語法簡介

(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 [email protected]
 * 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/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章