Devicetree Specification v0.4 核心属性实战:5分钟掌握 reg、interrupts 与 ranges 配置

📅 2026/7/6 1:39:45 👁️ 阅读次数 📝 编程学习
Devicetree Specification v0.4 核心属性实战:5分钟掌握 reg、interrupts 与 ranges 配置

Devicetree Specification v0.4 核心属性实战:5分钟掌握 reg、interrupts 与 ranges 配置

1. 设备树核心属性快速入门

对于Linux驱动开发者而言,设备树(Device Tree)已成为描述硬件资源的标准化方式。相比传统硬编码方式,设备树通过结构化数据分离硬件描述与驱动代码,极大提升了代码的可移植性。本文将聚焦三个最核心的属性配置:

reg属性:定义设备寄存器地址空间

  • 格式:<起始地址 长度> [起始地址2 长度2...]
  • 父节点的#address-cells#size-cells决定地址/长度所占单元格数

interrupts属性:声明设备中断信号

  • 格式:<中断号 触发方式>
  • 需配合interrupt-parent指定中断控制器

ranges属性:地址空间转换

  • 格式:<子地址 父地址 长度>
  • 用于不同总线地址域的映射

提示:设备树编译器(dtc)会将.dts文本转换为二进制.dtb文件,内核启动时解析此结构

2. 典型硬件配置实例分析

2.1 UART设备节点配置

uart0: serial@fe001000 { compatible = "ns16550a"; reg = <0xfe001000 0x100>; interrupts = <42 IRQ_TYPE_LEVEL_HIGH>; clock-frequency = <1843200>; status = "okay"; };

关键参数解析:

  • reg:UART寄存器基地址0xfe001000,范围256字节
  • interrupts:中断号42,高电平触发
  • clock-frequency:波特率时钟1.8432MHz

2.2 GPIO控制器配置

gpio: gpio-controller@ff710000 { compatible = "snps,dw-apb-gpio"; reg = <0xff710000 0x1000>; #gpio-cells = <2>; interrupts = <15 IRQ_TYPE_EDGE_RISING>; gpio-ranges = <&pinctrl 0 0 32>; };

特殊属性说明:

  • #gpio-cells:定义GPIO描述符格式(通常为 )
  • gpio-ranges:GPIO编号与pinctrl的映射关系

2.3 带中断的外设配置

eth0: ethernet@1f000000 { compatible = "smsc,lan9118"; reg = <0x1f000000 0x1000>; interrupts = <28 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&intc>; phy-mode = "mii"; };

中断相关要点:

  • 当存在多个中断控制器时需显式指定interrupt-parent
  • 触发类型常用值:
    • IRQ_TYPE_LEVEL_HIGH/LOW:电平触发
    • IRQ_TYPE_EDGE_RISING/FALLING:边沿触发

3. 属性配置速查表

属性作用域格式示例必需父节点属性
reg设备节点<0x1000 0x100>#address-cells, #size-cells
interrupts设备节点<15 IRQ_TYPE_EDGE_RISING>interrupt-parent
ranges总线节点<0x0 0xe0000000 0x100000>子/父节点的#address-cells
#address-cells总线节点<1>-
#size-cells总线节点<1>-

4. 复合设备树示例

以下是一个包含多设备的完整DTS片段:

/ { #address-cells = <1>; #size-cells = <1>; intc: interrupt-controller@f0000000 { compatible = "arm,gic-400"; reg = <0xf0000000 0x1000>; interrupt-controller; #interrupt-cells = <3>; }; soc { #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xe0000000 0x10000000>; uart0: serial@1000 { compatible = "ns16550a"; reg = <0x1000 0x100>; interrupts = <0 8 4>; /* SPI 8, level-high */ clocks = <&osc24m>; }; i2c@2000 { #address-cells = <1>; #size-cells = <0>; reg = <0x2000 0x100>; eeprom@50 { compatible = "atmel,24c02"; reg = <0x50>; }; }; }; };

5. 调试与验证技巧

  1. dtc编译检查

    dtc -I dts -O dtb -o output.dtb input.dts
  2. 内核启动参数

    bootargs = "earlycon devicetree=debug"
  3. 运行时查看

    ls /proc/device-tree/ cat /proc/device-tree/soc/serial@1000/compatible
  4. 常用调试工具

    • fdtdump:查看DTB二进制内容
    • dtc -I fs /sys/firmware/devicetree/base:导出运行时设备树

掌握这些核心属性的正确使用方式,可以解决90%的硬件描述问题。实际开发中建议结合具体芯片的参考手册,确保寄存器地址和中断号的正确性。