3. 设备树常用属性详解
设备树(Device Tree)中的属性(Property)是描述硬件配置与连接关系的基本单元。每个节点通过一组键值对(Key-Value Pair)向内核驱动程序传递硬件信息。本章将深入解析 compatible、reg、interrupts、status、model 等最常用的核心属性,涵盖其语法、语义、典型用法及常见陷阱。
学习提示: 设备树属性是驱动与硬件之间的“契约”。理解每个属性的确切含义,是编写正确、可移植 DTS 文件的基础。建议结合具体 SoC 参考手册对照学习。
3.1 compatible 属性:驱动匹配的“身份证”
compatible 属性是设备树中最关键的属性之一,它指定了设备与驱动程序的兼容性字符串。内核通过匹配该字符串来为设备节点绑定正确的驱动。
3.1.1 语法与规范
compatible = "manufacturer,model", "generic,model";
- 厂商前缀: 使用小写字母,如
ti、nxp、allwinner。 - 设备型号: 使用小写字母和数字,如
dm9000、i2c-gpio。 - 兼容列表: 可以指定多个字符串,优先级从前往后。内核会依次尝试匹配。
3.1.2 匹配优先级与回退机制
| 字符串顺序 | 含义 | 示例 |
|---|---|---|
| 第一个 | 最精确的硬件型号 | "ti,am335x-uart" |
| 第二个 | 兼容的通用型号 | "ti,omap-uart" |
| 第三个 | 更通用的标准接口 | "ns16550" |
实战要点: 编写驱动时,应在 of_match_table 中按精确到通用的顺序列出 compatible 字符串。设备树中的顺序应与驱动匹配表顺序一致。
3.1.3 内联 SVG:compatible 匹配流程
3.2 reg 属性:描述设备地址空间
reg 属性用于描述设备在总线上的地址范围,包括起始地址和长度。它是内存映射设备、I2C/SPI 从设备等场景的核心属性。
3.2.1 基本语法
reg = <address1 length1 address2 length2 ...>;
- address: 设备基地址,可以是 32 位或 64 位,由
#address-cells决定。 - length: 地址空间大小,由
#size-cells决定。
3.2.2 不同总线下的 reg 用法
| 总线类型 | #address-cells | #size-cells | reg 示例 | 说明 |
|---|---|---|---|---|
| 内存映射 (AMBA/AXI) | 1 | 1 | <0x1c20000 0x1000> |
基址 0x1c20000,大小 4KB |
| I2C | 1 | 0 | <0x50> |
从设备地址 0x50 |
| SPI | 1 | 0 | <0> |
片选编号 0 |
| PCIe | 3 | 2 | <0x02000000 0x0 0x40000000 0x0 0x40000000 0x0 0x100000> |
PCIe 标准地址格式 |
3.2.3 多段地址空间
某些设备拥有多个不连续的地址段,例如包含控制寄存器和数据缓冲区。此时可以在 reg 中依次列出:
reg = <0x10000000 0x1000>, /* 控制寄存器 */
<0x20000000 0x4000>; /* 数据缓冲区 */
常见错误: 忘记在父节点中正确设置 #address-cells 和 #size-cells,导致内核解析 reg 时地址或长度位数错误,造成驱动无法正确访问硬件。
3.3 interrupts 属性:连接中断控制器
interrupts 属性描述设备的中断请求线(IRQ)信息,包括中断号、触发类型等。它必须与父节点的 interrupt-parent 或全局的 interrupt-parent 配合使用。
3.3.1 标准格式
interrupts = <interrupt-specifier>;
interrupt-parent = <&gpio2>;
其中 interrupt-specifier 的格式由中断控制器的 #interrupt-cells 属性定义。
3.3.2 常见中断控制器类型
| 中断控制器 | #interrupt-cells | 中断说明符格式 | 示例 |
|---|---|---|---|
| GIC (ARM Generic) | 3 | <中断类型 中断号 触发方式> | <0 89 4> |
| GPIO 控制器 | 2 | <GPIO引脚 触发方式> | <5 IRQ_TYPE_EDGE_RISING> |
| 简单中断控制器 | 1 | <中断号> | <10> |
3.3.3 中断触发类型宏
#define IRQ_TYPE_NONE 0
#define IRQ_TYPE_EDGE_RISING 1
#define IRQ_TYPE_EDGE_FALLING 2
#define IRQ_TYPE_LEVEL_HIGH 4
#define IRQ_TYPE_LEVEL_LOW 8
3.3.4 内联 SVG:中断路由架构
3.4 status 属性:设备状态控制
status 属性用于控制设备节点的启用或禁用状态,是设备树中实现硬件裁剪和配置灵活性的关键属性。
3.4.1 可选值
| 值 | 含义 | 内核行为 |
|---|---|---|
"okay" |
设备已启用且功能正常 | 内核会尝试为该设备绑定驱动 |
"disabled" |
设备被禁用 | 内核不会为该设备创建 platform device |
"reserved" |
设备保留,不由操作系统管理 | 内核跳过该设备 |
"fail" |
设备检测失败 | 内核不会枚举该设备 |
3.4.2 典型应用场景
/* 在 SoC 级 DTSI 中默认禁用 */
&uart2 {
status = "disabled";
};
/* 在板级 DTS 中按需启用 */
&uart2 {
status = "okay";
pinctrl-0 = <&uart2_pins>;
pinctrl-names = "default";
};
最佳实践: SoC 级 DTSI 文件应将所有外设默认设为 "disabled",板级 DTS 文件再根据实际硬件连接逐个启用。这种分层设计避免了未使用外设占用资源。
3.5 model 属性:板级标识
model 属性用于描述设备或板卡的型号名称,通常放在根节点中,作为整个系统的标识符。
3.5.1 语法与规范
model = "Manufacturer, Board Name Rev X.Y";
- 厂商名: 使用标准厂商名称,如
Texas Instruments、NXP Semiconductors。 - 板卡名: 包含产品系列和版本号,如
AM335x EVM Rev 2.0。
3.5.2 与 compatible 的区别
| 属性 | 作用范围 | 用途 | 示例 |
|---|---|---|---|
model |
整个板卡或系统 | 用户空间识别硬件平台 | "TI AM335x EVM" |
compatible |
单个设备节点 | 内核驱动匹配 | "ti,am335x-uart" |
3.6 其他常用属性速查
| 属性名 | 用途 | 典型值示例 |
|---|---|---|
clock-frequency |
指定设备工作频率(Hz) | <24000000> |
pinctrl-0 |
引脚复用配置引用 | <&uart0_pins> |
pinctrl-names |
引脚配置状态名称 | "default", "sleep" |
dmas |
DMA 通道描述 | <&edma0 12> |
dma-names |
DMA 通道名称 | "rx", "tx" |
power-domains |
电源域引用 | <&pd_core> |
resets |
复位控制器引用 | <&rst 5> |
3.7 综合实战:完整设备节点示例
以下是一个集成了多个核心属性的完整 I2C 设备节点示例:
/* I2C 控制器节点 */
i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c", "ti,i2c-omap";
reg = <0x44e0b000 0x1000>;
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
status = "okay";
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
/* I2C 从设备:温度传感器 */
tmp102: temperature-sensor@48 {
compatible = "ti,tmp102";
reg = <0x48>;
interrupt-parent = <&gpio2>;
interrupts = <5 IRQ_TYPE_EDGE_RISING>;
status = "okay";
};
};
代码解析:
compatible使用两级回退:先匹配ti,omap4-i2c,失败则回退到ti,i2c-omap。reg定义 I2C 控制器寄存器基址 0x44e0b000,大小 4KB。interrupts使用 GIC 中断说明符,SPI 类型、中断号 70、高电平触发。- 从节点
tmp102的reg表示 I2C 从设备地址 0x48。 - 从节点通过
interrupt-parent指定使用 GPIO2 作为中断控制器。
3.8 常见错误与调试技巧
| 错误现象 | 可能原因 | 排查方法 |
|---|---|---|
| 驱动 probe 不执行 | compatible 字符串不匹配 | 检查 /sys/firmware/devicetree/base/ 下的节点内容 |
| 中断不触发 | interrupt-parent 指向错误 | 查看 /proc/interrupts 确认中断号分配 |
| 设备地址访问异常 | reg 中 address-cells/size-cells 不匹配 | 使用 dtc -I dtb -O dts 反编译确认 |
| 设备未枚举 | status 为 "disabled" 或缺失 | 检查 DTS 中 status 属性值 |
调试利器: 内核启动参数添加
of_debug=1 可以打印设备树匹配过程的详细信息,是排查 compatible 匹配问题的首选方法。
3.9 内联 SVG:核心属性关系总览
3.10 本章小结
- compatible 是驱动匹配的核心,支持多级回退机制。
- reg 描述设备地址空间,其解析依赖于父节点的 address-cells 和 size-cells。
- interrupts 与 interrupt-parent 配合,构建完整的中断路由链路。
- status 控制设备启用/禁用,是设备树分层设计的关键。
- model 提供板级标识,用于用户空间识别硬件平台。
- 所有属性必须严格遵循其所属总线的规范,否则会导致驱动加载失败或硬件访问异常。