文章目录
一、设备树介绍
设备树(DeviceTree,简称DT)是一种在嵌入式系统中描述硬件设备的一种数据结构和编程语言。它用于将硬件设备的配置信息以树状结构的形式进行描述,便于操作系统(如Linux)可以按照这种信息正确地辨识、配置和管理硬件设备。
设备树最初被引入到Linux内核中,用于解决硬件平台多样性带来的问题。传统上,Linux内核在编译时须要包含大量的硬件配置信息,这对于支持多种硬件平台的嵌入式系统来说是不实际的。设备树的引入促使硬件配置信息可以从内核中分离下来,作为一种独立的描述性数据结构进行管理,因而实现了硬件配置的可移植性和灵活性。
设备树一般以.dts(DeviceTreeSource)文件的方式存在,它是一种类似于C语言的句型,用于描述硬件设备的属性、寄存器地址、中断等信息。.dts文件经过编译后会生成.dtb(DeviceTreeBlob)文件,它是一种二补码格式的设备树表示方式,可以被Linux内核加载并解析。
在Linux内核启动时,设备树会被加载并传递给内核,供内核使用。内核通过解析设备树可以动态地配置硬件设备,加载对应的驱动程序,并完善设备之间的关联关系。
设备树的使用促使嵌入式系统在支持多种硬件平台时愈发灵活和可扩充,同时也提供了一种标准化的描述硬件设备的方法,以便硬件厂商、开发者和社区之间的协作和交流。
设备树描述硬件资源时有两个特征:
①树的主干就是系统总线,在设备树上面称为“根节点”。IIC控制器、GPIO控制器、SPI控制器等都是接到系统主线上的分支,在设备树里称为“根节点的子节点”。
②设备树可以像头文件(.h文件)那样,一个设备树文件引用另外一个设备树文件,这样可以实现“代码”的重用。诸如多个硬件平台都使用i.MX6ULL作为主控芯片,这么我们可以将i.MX6ULL芯片的硬件资源讲到一个单独的设备树文件上面通常使用“.dtsi”后缀,其他设备树文件直接使用“#includexxx”引用即可。
DTS、DTC和DTB它们是文档中常见的几个简写。
二、设备树框架1.设备树框架
我们可以通过路径imx6ull/bsp/kernel/linux-imx/arch/arm/boot/dts/下可以查看igkboard.dts设备树文件如下:
/dts-v1/;
#include "imx6ull.dtsi" /*头文件*/
/*设备树根节点*/
/ {
model = "LingYun IoT System Studio IoT Gateway Board"; /*model属性,用于指定设备的制造商和型号*/
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull"; /*compatible属性,系统用来决定绑定到设备驱动的关键,用来查找节点的方法之一*/
/*根节点的子节点*/
chosen {
stdout-path = &uart1;
};
/*根节点的子节点*/
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x20000000>;
};
/*根节点的子节点*/
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0xa000000>;
linux,cma-default;
};
};
/*根节点的子节点*/
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_leds>;
status = "okay";
sysled {
lable = "sysled";
gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
};
/*-------------以下内容省略-------------*/
};
/*设备树节点追加内容*/
/*+--------------+
| Misc Modules |
+--------------+*/
/*而是向原有节点追加内容*/
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
&pwm1 { /* backlight */
#pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&pwm2 {
#pwm-cells = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
};
我们可见设备文件分三个部份:
设备树由一个根节点和诸多子节点组成,子节点也可以继续包含其他节点,也就是子节点的子节点。设备树的组成很简单,下边我们一上去瞧瞧节点的基本格式和节点属性。
2.节点基本格式
设备树节点是一种以树状结构组织的硬件描述文件,描述了嵌入式系统中所有硬件设备的信息,包括设备的类型、地址、中断等信息。设备树节点的基本格式如下:
node-name@address {
compatible = "compatible-string";
reg = <address size>;
interrupt-parent = <&parent-node>;
interrupts = <irq1 flags1 irq2 flags2 ...>;
// other properties
};
其中:
设备树最主要的内容是编撰节点的节点属性,一般情况下一个节点代表一个设备。
3.节点部份属性简介
patible属性
compatible属性值由一个或多个字符串组成,有多个字符串时使用“,”分隔开。
设备树中的每一个设备的节点都要有一个compatible属性。系统通过compatible属性决定绑定哪一个设备的设备驱动,是拿来查找节点的方式之一,也可以通过节点名或节点路径查找指定节点。
比如系统初始化时会初始化platform总线上的设备时,依据设备节点”compatible”属性和驱动中of_match_table对应的值加载对应的驱动。
2.model属性
model属性用于指定设备的制造商和机型。
3.status属性
状态属性用于指示设备的“操作状态”,通过status可以去严禁设备或则启用设备,默认情况下不设置status属性设备是使能的。
4.#address-cells和#size-cells
#size-cells和#address-cells决定了子节点的reg属性中什么数据是“地址”,什么数据是“长度”信息。
#address-cells,用于指定子节点reg属性“地址数组”所占的宽度(单元格cells的个数)。
#size-cellslinux设备驱动开发linux系统命令,用于指定子节点reg属性“大小数组”所占的宽度(单元格cells的个数)。
比如#address-cells=2,#address-cells=1,则reg内的数据涵义为reg=
,每位cells是一个32显存的数字。
5.reg属性
ret属性的书写格式为reg=
reg属性描述设备资源在其父总线定义的地址空间内的地址。一般情况下用于表示一块寄存器的起始地址(偏斜地址)和厚度,在特定情况下也有不同的含意。
比如#address-cells=,#address-cells=,reg=,其中0x9000000表示的是地址,0x4000表示的是地址宽度,这儿的reg属性指定了起始地址为0x9000000,厚度为0x4000的一块地址空间。
6.ranges
该属性提供了子节点地址空间和父地址空间的映射(转换)方式,常见格式是。假如父地址空间和子地址空间相同则无需转换。
例如对于#address-cells和#size-cells都为1的话,以ranges=为例,表示将子地址的从0x0~(0x0+0x20)的地址空间映射到父地址的0x10~(0x10+0x20)。
7.name和device_type
这两个属性极少用(早已被废弃)linux设备驱动开发,不推荐使用。name用于指定节点名,在旧的设备树中它用于确定节点名,如今我们使用的设备树早已弃用。device_type属性也是一个极少用的属性,只用在CPU和显存的节点上。如上例中所示,device_type用在了CPU节点。
我们在设备树中添加了一个“led”节点,正常情况下我们可以从这个节点获取编撰led驱动所用到的所有信息linux视频教程,比如led相关控制寄存器地址、led时钟控制寄存器地址等等。
内核提供了一组函数用于从设备节点获取资源(设备节点中定义的属性)的函数,这种函数以of_开头,称为OF操作函数。
总结
本篇博客主要介绍了设备树(DeviceTree)的基本概念和框架。首先,简单介绍了设备树的作用,即为系统中的硬件设备提供描述信息,帮助内核辨识和驱动硬件设备。其次,详尽介绍了设备树的基本框架,包括节点标签、节点路径和节点属性。其中,节点标签用于表示设备节点的类型和名称,节点路径用于表示设备节点在设备树中的位置,节点属性用于描述设备节点的各类属性信息。最后,针对节点属性,本篇博客简单介绍了一些常见的属性类型和属性值。
总体而言,本篇博客为读者提供了一个基础的设备树入门手册,使读者才能了解设备树的基本概念和框架。读者可在此基础上进一步深入学习设备树,并在实际开发中应用设备树技术。