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. 调试与验证技巧
dtc编译检查:
dtc -I dts -O dtb -o output.dtb input.dts内核启动参数:
bootargs = "earlycon devicetree=debug"运行时查看:
ls /proc/device-tree/ cat /proc/device-tree/soc/serial@1000/compatible常用调试工具:
fdtdump:查看DTB二进制内容dtc -I fs /sys/firmware/devicetree/base:导出运行时设备树
掌握这些核心属性的正确使用方式,可以解决90%的硬件描述问题。实际开发中建议结合具体芯片的参考手册,确保寄存器地址和中断号的正确性。
