【嵌入式Linux学习笔记】Linux设备树

在这里插入图片描述

Linux的设备树将每个外设都视为一个节点,整体架构很明确清晰,也很便于设备管理。

学习视频地址:【正点原子】STM32MP157开发板

1. 设备树结构

在这里插入图片描述

2. 文件关系

DTC:编译器
DTS:设备树源文件
DTSI:设备树头文件
DTB:设备树编译所得文件

编译设备树

需进入到Linux内核源码目录

make dtbs # 编译所有设备树
make xxx.dtb # 编译某个设备树

3. 设备树语法

设备节点

命名格式

node-name@unit-address # unit-address表示设备地址或寄存器首地址
label: node-name@unit-address # label可以便于访问节点

数据形式

compatible = "arm,cortex-a7"; # 字符串
reg = <0 0x123456 100> # 32位无符号整数
compatible = "st,stm32mp157d-atk", "st,stm32mp157"; # 字符串列表

标准属性

compatible:兼容性属性,用于将设备和驱动进行绑定,格式如下,前者为厂商,后者为驱动名字

compatible = "manufacturer,model"

model:描述开发板的名字或者设备模块信息

model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";

status:状态属性
在这里插入图片描述
#address-cells 和#size-cells:长度属性
这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells 属性值决定了子节点 reg 属性中地址信息所占用的字长(32 位),#size-cells 属性值决定了子节点 reg 属性中长度信息所占的字长(32 位)。

reg:寄存器属性

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

ranges:地址映射/转换表
属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字
矩阵,ranges 属性每个项目由子地址、父地址和地址空间长度这三部分组成:

child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells 确定此物理地址 所占用的字长。
parent-bus-address:父总线地址空间的物理地址,同样由父节点的#address-cells 确定此物 理地址所占用的字长。
length:子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。

特殊节点

aliases:定义别名

aliases {
	serial0 = &uart4;
};

chosen: uboot向Linux内核传递数据,如以下这样子定义属性之后,chosen中会存在bootargs和stdout-path两个属性

chosen {
	stdout-path = "serial0:115200n8";
};

向节点追加信息

以在i2c节点下添加fxls8471芯片节点为例,我们需要在.dts文件中添加相应的内容,这样子不会影响其他引用了i2c所在的.dtsi文件的设备树

&i2c1 {
 /* 要追加或修改的内容 */
};
#例
&i2c1 {
	 pinctrl-names = "default", "sleep";
	 pinctrl-0 = <&i2c1_pins_b>;
	 pinctrl-1 = <&i2c1_pins_sleep_b>;
	 status = "okay";
	 clock-frequency = <100000>;
 
	 fxls8471@1e {
		 compatible = "fsl,fxls8471";
		 reg = <0x1e>;
		 position = <0>;
		 interrupt-parent = <&gpioh>;
		 interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
	 }; 
};

4. 设备树在代码文件中的使用

其实就是读取各个节点的信息,并把它们放入到代码变量中,从而实现各个功能配置。

dtsled.nd = of_find_node_by_path("/stm32mp1_led");
if(dtsled.nd == NULL) {
	printk("stm32mp1_led node nost find!\r\n");
	return -EINVAL;
} else {
	printk("stm32mp1_lcd node find!\r\n");
}

/* 2、获取compatible属性内容 */
proper = of_find_property(dtsled.nd, "compatible", NULL);
if(proper == NULL) {
	printk("compatible property find failed\r\n");
} else {
	printk("compatible = %s\r\n", (char*)proper->value);
}

/* 3、获取status属性内容 */
ret = of_property_read_string(dtsled.nd, "status", &str);
if(ret < 0){
	printk("status read failed!\r\n");
} else {
	printk("status = %s\r\n",str);
}

/* 4、获取reg属性内容 */
ret = of_property_read_u32_array(dtsled.nd, "reg", regdata, 12);
if(ret < 0) {
	printk("reg property read failed!\r\n");
} else {
	u8 i = 0;
	printk("reg data:\r\n");
	for(i = 0; i < 12; i++)
		printk("%#X ", regdata[i]);
	printk("\r\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

煜个头头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值