3. DTS 常用属性详解:compatible、reg、interrupts、status、model、device_type
设备树(Device Tree Source, DTS)通过一系列标准属性来描述硬件设备的特征、资源及拓扑关系。掌握这些核心属性是解析设备树、编写驱动的基础。本章将逐一剖析 compatible、reg、interrupts、status、model 和 device_type 六个最常用的属性,并结合驱动开发中的实际场景说明其用法。
3.1 compatible —— 设备与驱动的匹配密钥
compatible 属性是设备树中最重要的属性之一,它指定了设备的兼容性字符串列表。内核通过该属性将设备节点与对应的驱动程序进行绑定。
- 格式:
compatible = "manufacturer,model", "fallback-model"; - 匹配顺序:内核优先使用列表中的第一个字符串进行匹配;若失败,则依次尝试后续字符串。
- 命名规范:通常采用
"厂商名,设备型号"的形式,如"ti,am335x-uart"。
驱动匹配示例:在驱动中通过
of_match_table 声明支持的 compatible 列表,内核在解析设备树时会自动完成匹配。
// 设备树节点
uart0: serial@44e09000 {
compatible = "ti,am335x-uart", "ns16550a";
reg = <0x44e09000 0x2000>;
interrupts = <72>;
};
// 驱动端
static const struct of_device_id my_uart_of_match[] = {
{ .compatible = "ti,am335x-uart", .data = &am335x_data },
{ .compatible = "ns16550a", .data = &ns16550a_data },
{ /* end */ }
};
MODULE_DEVICE_TABLE(of, my_uart_of_match);
3.2 reg —— 描述设备地址空间
reg 属性用于描述设备在总线上的地址范围,通常包含起始地址和长度。它由 address-cells 和 size-cells 共同决定每个地址和长度字段的宽度。
| 属性 | 含义 | 示例值 |
|---|---|---|
#address-cells |
地址字段占用的 32 位单元数 | 1(32位地址)或 2(64位地址) |
#size-cells |
长度字段占用的 32 位单元数 | 1(32位长度)或 0(无长度) |
reg |
地址与长度交替排列的数组 | <0x44e09000 0x2000> |
// 64位地址空间示例
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
// 解释:起始地址 0x80000000,长度 0x40000000(1GB)
};
驱动开发提示:使用
of_iomap() 或 platform_get_resource() 可以方便地将 reg 描述的物理地址映射到内核虚拟地址空间。
3.3 interrupts —— 中断资源描述
interrupts 属性定义了设备使用的中断号、触发类型等信息。它依赖于 interrupt-parent 属性指向中断控制器节点。
- 中断控制器:通过
#interrupt-cells指定每个中断描述需要的单元数。 - 常见格式:
interrupts = <中断号 触发类型>或<中断号 中断标志 触发类型>。 - 触发类型:
0表示高电平触发,1表示低电平触发,2表示上升沿触发,3表示下降沿触发,4表示边沿触发。
// 设备节点
gpio_keys {
compatible = "gpio-keys";
interrupt-parent = <&gpio1>;
interrupts = <15 2>; // GPIO1_15,下降沿触发
...
};
常见错误:忘记指定
interrupt-parent 或中断号与硬件不一致,会导致驱动无法正确响应中断。务必核对芯片手册中的中断映射表。
3.4 status —— 设备状态控制
status 属性用于指示设备的启用状态,是设备树中实现条件编译或运行时控制的重要手段。
| 取值 | 含义 | 驱动行为 |
|---|---|---|
"okay" |
设备正常启用 | 内核会尝试绑定驱动并初始化 |
"disabled" |
设备禁用 | 内核跳过该节点,不创建设备 |
"fail" |
设备检测失败 | 内核标记为失败,不绑定驱动 |
"reserved" |
保留状态 | 通常用于特殊用途,驱动需特殊处理 |
// 在 board.dts 中覆盖 SoC 默认状态
&uart1 {
status = "okay"; // 启用 UART1
};
&i2c0 {
status = "disabled"; // 禁用 I2C0
};
3.5 model —— 设备型号标识
model 属性用于描述设备或板卡的型号名称,通常是一个可读的字符串。它主要用于调试和日志输出,不参与驱动匹配。
- 典型用法:
model = "TI AM335x BeagleBone Black"; - 作用:帮助开发者和工具识别硬件平台,在
/proc/device-tree/中可见。 - 与 compatible 的区别:
compatible用于驱动匹配,model仅用于标识。
3.6 device_type —— 设备类型(已废弃)
device_type 属性在早期的设备树规范中用于标识设备类型,如 "memory"、"cpu"、"pci" 等。但在 ePAPR v1.1 之后,该属性已被标记为废弃,仅保留对 "memory" 和 "cpu" 的兼容性支持。
最佳实践:新编写的设备树节点不应使用
device_type,除非是必须兼容老旧内核的 memory 或 cpu 节点。驱动开发中应避免依赖此属性。
// 仅 memory 和 cpu 节点仍可能使用 device_type
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x40000000>;
};
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0>;
};
3.7 属性关系与驱动解析流程
下图展示了内核在设备树解析过程中,如何利用上述属性完成设备注册与驱动匹配的完整流程。
3.8 属性对比与使用建议
| 属性 | 是否参与驱动匹配 | 是否必须 | 驱动常用 API |
|---|---|---|---|
compatible |
是 | 是 | of_match_device() |
reg |
否 | 通常必须 | of_iomap()、platform_get_resource() |
interrupts |
否 | 有中断时必须 | irq_of_parse_and_map() |
status |
否 | 可选 | of_device_is_available() |
model |
否 | 可选 | of_property_read_string() |
device_type |
否 | 已废弃 | 不推荐使用 |
学习建议:在编写驱动时,优先从设备树中读取
compatible 和 reg 属性;对于中断驱动的设备,务必检查 interrupt-parent 和 interrupts 的对应关系。使用 status 属性可以方便地在不同板级配置中启用或禁用外设,避免修改驱动代码。