给嵌入式Linux新手的设备树dts语法速查手册:从根节点到中断,一篇搞定

张开发
2026/4/21 9:08:07 15 分钟阅读

分享文章

给嵌入式Linux新手的设备树dts语法速查手册:从根节点到中断,一篇搞定
嵌入式Linux设备树dts语法实战速查指南刚接触嵌入式Linux开发的工程师第一次看到设备树源文件.dts时往往会感到困惑——这些层层嵌套的节点和属性到底该怎么写为什么我的板子启动时内核总是提示Missing interrupt-parent这份速查手册就是为了解决这些问题而生。不同于系统性的教程我们聚焦于开发中最常遇到的语法问题用最短的时间帮你找到正确答案。1. 节点与属性速查从零开始构建设备树设备树的核心就是节点node和属性property的组合。想象你在搭建一个乐高模型节点就是各种积木块属性则是连接这些积木的接口规范。1.1 节点命名规范每个节点都遵循node-nameunit-address的命名格式cpu0 { // 正确字母开头包含地址 // 节点内容 }; _uartfe001000 { // 正确允许下划线开头 3com,serial-port; // 错误节点名不能以数字开头 };常见错误排查节点名包含非法字符如空格、$、*等忘记添加unit-address当节点有reg属性时必须地址值与reg属性不匹配1.2 属性值类型速查表设备树支持多种属性值类型以下是快速对照表类型示例说明u320x1234567832位无符号整数u640x11223344 0x5566778864位整数两个u32组成stringhello,world以\0结尾的字符串bytestring[00 11 22 33]十六进制字节序列phandlenode_label引用其他节点的标识符stringlistvalue1, value2多个字符串组成的列表提示phandle引用时确保目标节点已定义且具有唯一标签2. 特殊节点详解你必须知道的四个关键结构设备树中有几个特殊节点承担着系统级功能它们的正确配置直接影响系统启动。2.1 内存节点(/memory)描述物理内存布局每个内存区域需要一个独立节点// 典型双内存配置示例 memory0 { device_type memory; reg 0x00000000 0x80000000; // 起始地址0大小2GB }; memory100000000 { device_type memory; reg 0x100000000 0x40000000; // 起始地址4GB大小1GB };常见问题忘记设置device_type属性reg属性地址/大小与硬件不符大小单位错误应使用字节2.2 别名节点(/aliases)为长路径节点创建简短别名aliases { serial0 uart1; // 通过标签引用 ethernet0 /soc/ethernet1c30000; // 直接路径引用 };2.3 中断控制器配置中断系统是设备树中最复杂的部分之一。一个典型配置包含intc: interrupt-controller48200000 { compatible ti,omap3-intc; interrupt-controller; #interrupt-cells 1; reg 0x48200000 0x1000; }; gpio_keys { compatible gpio-keys; interrupt-parent intc; // 引用中断控制器 interrupts 14 IRQ_TYPE_EDGE_FALLING; // 中断号14下降沿触发 };关键检查点中断控制器必须声明interrupt-controller属性#interrupt-cells定义中断描述符的单元数设备节点必须通过interrupt-parent指定控制器3. 核心属性实战解析3.1 compatible属性驱动匹配的关键这个属性决定了内核如何为设备选择驱动程序// 多厂商兼容示例 ethernet1c30000 { compatible ti,dm8168-emac, ti,dm816-emac; // 先尝试ti,dm8168-emac驱动失败则使用更通用的ti,dm816-emac };最佳实践优先使用芯片厂商提供的准确型号添加一个通用后备选项确保内核已编译对应驱动3.2 reg属性地址空间映射reg属性通常与#address-cells/#size-cells配合使用soc { #address-cells 1; #size-cells 1; serial101f0000 { compatible arm,pl011; reg 0x101f0000 0x1000; // 起始地址0x101f0000长度4KB }; };常见错误地址/大小与硬件手册不符忘记设置父节点的#address-cells/#size-cells大小单位混淆地址通常为16进制大小为十进制4. 中断系统深度配置4.1 多级中断控制器复杂SoC通常具有多级中断控制器gic: interrupt-controller2c001000 { compatible arm,cortex-a9-gic; #interrupt-cells 3; interrupt-controller; reg 0x2c001000 0x1000, 0x2c002000 0x1000; }; gpio0: gpio44e07000 { compatible ti,omap4-gpio; interrupt-parent gic; interrupts 0 20 IRQ_TYPE_LEVEL_HIGH; gpio-controller; #gpio-cells 2; }; keyboard { compatible gpio-keys; interrupt-parent gpio0; interrupts 1 IRQ_TYPE_EDGE_FALLING; };4.2 中断属性对照表属性适用场景示例值interrupts单一中断控制器0 120 IRQ_TYPE_LEVEL_HIGHinterrupts-extended多中断控制器intc1 5, intc2 3 0interrupt-parent指定默认中断控制器gic#interrupt-cells定义中断描述符格式2或3interrupt-controller声明节点为中断控制器空属性5. 调试技巧与常见陷阱5.1 设备树编译器(dtc)检查在部署前务必进行语法检查# 编译检查 dtc -O dtb -o output.dtb -b 0 input.dts # 反编译验证 dtc -I dtb -O dts output.dtb5.2 内核启动参数添加调试参数获取设备树解析信息# 在bootargs中添加 bootargs ... dtbdebug1 ignore_loglevel;典型错误场景中断无法触发检查interrupt-parent和interrupts是否匹配控制器要求驱动未加载确认compatible值与驱动代码一致内存映射失败验证reg属性与硬件手册的一致性地址越界检查父节点的#size-cells设置在最近的一个工业控制器项目中我们发现SPI设备无法正常工作最终通过对比设备树中的reg属性与芯片手册发现地址偏移量少算了一个0。这种低级错误往往最耗时希望这份速查手册能帮你快速定位这类问题。

更多文章