设备树之节点和属性

设备树概图

下图中看上去比较简单,实际上包含了设备树的很多重要信息,主要是节点和属性。
设备树例子

节点

节点格式:

node-name@unit-address

其中“node-name”是节点名字,为 ASCII 字符串,节点名字应该能够清晰的描述出节点的功能,比如“uart”就表示这个节点是 UART外设。“unit-address”一般表示设备的地址或寄存器首地址,如果某个节点没有地址或者寄存器的话“unit-address”可以没有。

别名节点

aliases 的意思是“别名”,因此 aliases 节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。有时候引用的节点可读性很差,这个时候就可以定义一个简单的易于理解的名字。
在系统的中的定义如下:

aliases {
serial0 = "/simple-bus@fe000000/serial@llc500";
ethernet0 = "/simple-bus@fe000000/ethernet@31c000";
};

获取节点属性函数:

int of_alias_get_id(struct device_node *np, const char *stem)

chosen节点

在系统中/chosen节点并不是代表一个真正的设备,但是可以在运行的时候描述参数或者固件。它必须是root的子节点。

chosen {
	bootargs = "console=NULL,115200 earlycon=ec_imx6q,0x30890000,115200";
	stdout-path = &uart2;
};

它包含的三种属性:bootargs、stdout-path、stdin-path。

label

首先,它代表的是一个节点,label主要是用于给节点加上标签,让节点有一个唯一的名字,方便访问节点,可以直接通过&label 来访问,在设备树编译器编译之后会给定一个唯一的32位值。
label的定义格式如下:

[label:] node-name[@unit-address] {
	[properties definitions]
	[child nodes]
};

“:”前面的是节点标签(label),“:”后面的是节点名字。
具体实例:

	gpio1: gpio@30200000 {
		compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio";
		reg = <0x0 0x30200000 0x0 0x10000>;
		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
			     <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
	};

属性

phandle

phandle属性就是在devicetree中定义一个唯一的数字标识符,注意:不要跟其他的phandle值一样),例如:
pic@10000000 {
	phandle = <1>;
	interrupt-controller;
};

比如需要在另外的地方引用上面的节点,可以这样使用:

another-device-node {
	interrupt-parent = <1>;
};

注意:大多数时候在设备树源码中不会显示的包含phandle属性,但是DTC工具在将DTS编译成二进制DTB的时候会自动的插入phandle属性

#address-cells 和 #size-cells

这两个属性可以用在任何设备树层次结构中带有子节点的设备节点中。#address-cells的数值用于定义子节点的reg属性的地址域;#size-cells数值用于定义子节点属性reg的大小。它们必须显示的定义,不能从设备树的上代继承。如果没有定义的话默认#address-cells=2默认size-cells=2。

/ {
	compatible = "fsl,imx8mm";
	interrupt-parent = <&gpc>;
	#address-cells = <2>;
	#size-cells = <2>;
	...
	memory@40000000 {
		device_type = "memory";
		reg = <0x0 0x40000000 0 0x80000000>;
	};

在上面的代码中reg的起始地址为0x0000000040000000,大小为0x0000000080000000。

reg

reg 属性的值一般是 (address, length) 对,reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。
定义的格式如下:

reg = <address1 length1 address2 length2 address3 length3……>

举例:一个设备有两个寄存器块,一个的地址是0x3000,占据32字节;另一个的地址是0xFE00,占据256字节,表示如下:

reg = <0x3000 0x20 0xFE00 0x100>;	//对应#address-cells = <1>; #size-cells = <1>;。

获取属性函数

获取字符串

dts定义:
string-property = "a string";
函数原型:
int of_property_read_string(const struct device_node *np, const char *propname, const char **out_string)
获取数据:
const char *my_string = NULL; 
of_property_read_string(pdev->dev.of_node, "string-property", &my_string);

获取u32整形数据

dts定义:
one-int-property = <197>; 
int-list-property = <1350000 0x54dae47 1250000 1200000>; 

函数原型:
int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)  
获取一个数据:
unsigned int number; 
of_property_read_u32(pdev->dev.of_node, "one-cell-property", &number);  

函数原型:
int of_property_read_u32_array(const struct device_node *np,  const char *propname, u32 *out_values, size_t sz);  
获取多个数据:
unsigned int cells_array[4]; 
if (of_property_read_u32_array(pdev->dev.of_node, "int-list-property", cells_array, 4)) { 
    dev_err(&pdev->dev, "list of cells not specified\n"); 
    return -EINVAL;
}

参考资料

《Devicetree SpecificationV0.2.pdf》

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值