1.概念:
设备树英文名称 Device Tree,是一个由节点和属性 构成的树形结构。属性的形式为键值对,节点可以包含属性,同时也可以包含子节点。
例如:
/dts-v1/;
/ {
node1 {
a-string-property = "A string";
a-string-list-property = "first string", "second string";
// hex is implied in byte arrays. no '0x' prefix is required
a-byte-data-property = [01 23 34 56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
child-node1 {
};
};
};
上述设备树包含:
1) . 根节点: "/"
2) .子节点 node1和node2
3) . node1的子节点 child-node1,child-node2
4) .其他属性
2.属性的介绍
属性一般以键值对形式出现,值可以为空或者为任意字节流。设备树中的数据类型一般有以下几种形式:
1) string类型,如
string-property = "a string";
2)32位无符号整型数
cell-property = <0xbeef 123 0xabcd1234>;
3) 二进制数
binary-property = [0x01 0x23 0x45 0x67];
4) 混合数据
mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678>;
5) string list
mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678>;
3. 设备树文件格式
***.dts //设备树的源码文件
***.dtsi //设备树源码文件的补充文件(头文件)
DTC //设备树编译工具 make dtbs
***.dtb//设备树的 二进制文件
4. 设备树节点的命名
设备树节点命名规则:[@
:设备树节点的名字,是一个简单的 ASCII 字符串,长度最多为 31 个字符。通常,节点是根据它所代表的设备类型来命名的。
[@:如果当前节点描述的设备是一个可寻址设备,可以在@后面写上设备的寻址地址
ex: gpio@50006000//GPIOE控制器节点命名
5. 设备树节点起别名以及引用
1.
aliases {
serial0 = &uart4;
serial5 = &usart3;
};
//serial0相当于给uart4节点起了别名
//&表示引用后面的节点
2.
reserved-memory {
gpu_reserved: gpu@d4000000 {
reg = <0xd4000000 0x4000000>;
no-map;
};
//gpu_reserved相当于是给gpu@d4000000起了一个别名
3.
在1.dts文件中有如下节点
/{
node1{
p1="aaa";
p2="bbb";
};
};
在2.dts文件中有如下内容:
/{
};
&node1{
p1="ccc";
p3="ddd";
};
//在2.dts文件中引用1.dts文件中的node1节点
//两个dts文件中都有关于node1节点的描述
//如果描述中同级节点下有相同的属性名,后一次的会覆盖前一次的,如果属性名不同,则合并
node1{
p1="ccc";
p2="bbb";
p3="ddd";
};
6. 在设备树中有一些特定意义的键名
compatible=“厂商名,设备名”//用来描述设备厂商信息
#address-cells = <n>//当前节点的子节点的地址信息用n个u32类型数据描述
#size-cells= <n>//当前节点的子节点的地址大小用n个u32类型数据描述
reg= <addr size>,<addr size>,...//描述当前节点对应的设备的地址信息
7. 在驱动中获取设备信息
假设我们在设备树中添加的节点信息如下:
mynode@0x12345678{
compatible = "hqyj,mynode";
astring="hello 22111";
uint =<0xaabbccdd 0x11223344>;
binarry=[00 0c 29 7b f9 be];
mixed ="hello",[11 22],<0x12345678>;
};
1) 设备树节点结构体
#include<linux/of.h>
struct device_node {
const char *name;//节点名
const char *full_name;//全名
struct property *properties;//属性链表结点指针
struct device_node *parent;//当前节点父节点指针
struct device_node *child;//子节点指针
struct device_node *sibling;//兄弟节点
};
2) 属性结构体
struct property {
char *name;//键名
int length;//值的长度
void *value;//值
struct property *next;//指向下一个属性的指针
};
3) 获取设备树节点信息API
struct device_node *of_find_node_by_name(struct device_node *from,
const char *name);
功能:通过节点名字获取设备树节点信息
参数:
from:当前节点父节点,填写NULL,表示默认从根节点开始查找
name:设备树节点名 "mynode"
返回值: 成功返回目标设备树节点结构体指针,失败返回NULL
struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
功能:根据设备树节点在compatible的值来获取设备树节点信息
参数:
from:当前节点父节点,填写NULL,表示默认从根节点开始查找
type:设备类型,填NULL
compat:compatible的值
返回值: 成功返回目标设备树节点结构体指针,失败返回NULL
struct device_node *of_find_node_by_path(const char *path)
功能:根据设备树节点路径来获取设备树节点信息
参数:
path:指定的设备树节点路径 "/mynode@0x12345678"
返回值: 成功返回目标设备树节点结构体指针,失败返回NULL
********实现大小端转换的函数************
__u32 __be32_to_cpup(const __be32 *p)
功能:将32数据大端转小端
__be32 __cpu_to_be32p(const __u32 *p)
32位数小端转大端