3. 设备树常用属性详解:compatible、reg、interrupts、status、model 等核心属性

设备树(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 匹配流程

compatible 属性驱动匹配流程 设备树节点 compatible = "ti,am335x-uart", "ns16550" 内核 OF 匹配层 遍历 of_match_table 字符串逐项比较 驱动程序 probe() 回调 设备初始化 回退匹配通用型号

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:中断路由架构

设备树中断路由架构 UART 外设 interrupts = <0 89 4> interrupt-parent = <&gic> GIC-400 #interrupt-cells = <3> 中断类型: 0(SPI) 中断号: 89 CPU 核 0 IRQ 处理 中断服务例程 中断路由说明 1. 外设节点通过 interrupts 属性声明中断请求 2. interrupt-parent 指向中断控制器节点(GIC) 3. GIC 根据中断类型和号将中断路由到指定 CPU

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:核心属性关系总览

设备树核心属性关系总览 设备节点 (Device Node) compatible 驱动匹配标识 "厂商,型号" reg 地址空间描述 基址 + 长度 interrupts 中断请求描述 中断号 + 触发 status 设备状态控制 okay/disabled 底层依赖属性 #address-cells / #size-cells / #interrupt-cells / interrupt-parent pinctrl-0 / clock-frequency / dmas / power-domains

3.10 本章小结

  • compatible 是驱动匹配的核心,支持多级回退机制。
  • reg 描述设备地址空间,其解析依赖于父节点的 address-cells 和 size-cells。
  • interrupts 与 interrupt-parent 配合,构建完整的中断路由链路。
  • status 控制设备启用/禁用,是设备树分层设计的关键。
  • model 提供板级标识,用于用户空间识别硬件平台。
  • 所有属性必须严格遵循其所属总线的规范,否则会导致驱动加载失败或硬件访问异常。