2. DTS 语法基础:设备树源文件的基本结构与定义
设备树源文件(DTS)是描述硬件拓扑与资源配置的文本文件,采用树形层级结构组织。每个 DTS 文件由节点(node)和属性(property)构成,节点对应硬件设备或总线,属性描述设备的特性与配置参数。
2.1 DTS 文件的基本结构
一个典型的 DTS 文件包含以下部分:
- 根节点(/):设备树的顶层入口,所有设备节点均挂载在根节点下。
- 子节点:表示具体的设备或总线,如 CPU、内存、I2C 控制器、GPIO 控制器等。
- 属性:键值对形式,描述节点的硬件信息,如寄存器地址、中断号、时钟频率等。
- 包含文件:通过
#include引入 .dtsi 文件,实现 SoC 级公共定义的复用。
关键概念:DTS 文件采用 C 语言风格的注释(
// 和 /* */),支持宏定义和头文件包含,语法上类似 C 语言的结构体定义。
实践提示:实际项目中,SoC 厂商提供 .dtsi 文件定义芯片内部外设,板级开发者只需在 .dts 文件中引用并覆盖或添加板级特有设备。
2.2 节点(Node)的定义
节点是设备树的基本组成单元,语法格式如下:
[label:] node-name {
property1 = value1;
property2 = value2;
child-node {
...
};
};
节点定义的关键要素:
| 要素 | 说明 | 示例 |
|---|---|---|
| 节点名称 | 标识节点类型,通常为通用名称如 uart、i2c |
serial@101f0000 |
| 单元地址 | 可选,跟在节点名后以 @ 分隔,表示设备基地址 |
@101f0000 |
| 标签(label) | 可选,为节点起别名,便于引用或覆盖 | uart1: serial@101f0000 |
| 属性列表 | 花括号 { } 内包含多个属性定义 |
reg = <0x101f0000 0x1000>; |
| 子节点 | 节点内可嵌套子节点,形成层级结构 | clocks { ... }; |
常见错误:节点名称不能包含空格或特殊字符(除
@、-、_ 外);单元地址必须与 reg 属性中的首地址一致,否则编译报错。
2.3 属性(Property)的定义
属性是节点的数据载体,采用键值对形式。属性值支持多种数据类型:
| 数据类型 | 语法格式 | 示例 | 说明 |
|---|---|---|---|
| 空值 | property-name; |
interrupt-controller; |
仅表示存在该属性,无值 |
| 32 位整数 | <value> |
reg = <0x10000000 0x1000>; |
尖括号内可包含多个整数 |
| 64 位整数 | <high low> |
reg = <0x0 0x80000000 0x0 0x10000000>; |
高 32 位在前,低 32 位在后 |
| 字符串 | "string" |
compatible = "arm,cortex-a9"; |
双引号包裹 |
| 字符串列表 | "str1", "str2" |
compatible = "ti,am335x-uart", "ns16550"; |
逗号分隔多个字符串 |
| 字节数组 | [hex bytes] |
local-mac-address = [00 11 22 33 44 55]; |
方括号内为十六进制字节 |
| 混合值 | <...> "..." [...] |
gpios = <&gpio0 15 0>; |
可组合不同类型 |
2.4 标准属性与常用属性
设备树规范定义了一系列标准属性,用于描述设备的核心信息:
| 属性名 | 用途 | 示例值 |
|---|---|---|
compatible |
设备驱动匹配字符串,格式为 "厂商,型号" |
"ti,am335x-uart" |
reg |
设备寄存器地址与长度,格式为 <地址 长度> |
<0x44e09000 0x2000> |
interrupts |
中断号与触发类型 | <0 56 4> |
clocks |
时钟源引用 | <&clk_uart1_fck> |
status |
设备状态:okay、disabled、reserved |
"okay" |
#address-cells |
子节点 reg 中地址字段的 32 位字数量 |
<1> |
#size-cells |
子节点 reg 中长度字段的 32 位字数量 |
<1> |
2.5 完整 DTS 示例
以下是一个简化的 UART 设备节点定义,展示节点与属性的实际组合:
/dts-v1/;
/ {
model = "TI AM335x Board";
compatible = "ti,am335x-board";
chosen {
stdout-path = &uart0;
};
uart0: serial@44e09000 {
compatible = "ti,am335x-uart", "ns16550";
reg = <0x44e09000 0x2000>;
interrupts = <0 72 4>;
clock-frequency = <48000000>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = &uart0_pins;
};
uart0_pins: pinmux_uart0_pins {
pinctrl-single,pins = <
0x170 0x30 /* uart0_rxd */
0x174 0x00 /* uart0_txd */
>;
};
};
要点总结:
- 根节点
/包含model和compatible属性,标识板级信息。 chosen节点用于传递内核启动参数,如控制台设备。uart0节点通过compatible属性匹配驱动,reg描述寄存器地址,interrupts描述中断资源。pinctrl属性用于引脚复用配置,属于 SoC 特有的扩展属性。
2.6 节点引用与覆盖
设备树支持通过标签(label)引用节点,实现节点属性的覆盖或扩展:
// 在 .dtsi 文件中定义
uart0: serial@44e09000 {
compatible = "ti,am335x-uart";
status = "disabled";
};
// 在 .dts 文件中覆盖
&uart0 {
status = "okay";
clock-frequency = <48000000>;
};
引用语法 &label 允许在不重新定义整个节点的情况下,修改或添加属性。这是设备树实现板级差异化的核心机制。
工程实践:SoC 厂商在 .dtsi 中将外设节点
status 设为 disabled,板级 .dts 中仅使能实际使用的设备,避免未用设备占用资源。