1. 引言在嵌入式 Linux 开发中设备树Device Tree是连接硬件与驱动的重要桥梁。对于初学者而言理解设备树与 ARM 驱动的关系是掌握嵌入式 Linux 驱动开发的关键一步。本文基于实际学习过程总结设备树的基本概念、语法结构以及如何基于设备树编写 ARM Linux 驱动程序帮助读者建立从硬件描述到驱动实现的完整认知。2. 为什么需要设备树在早期的 Linux 内核中ARM 平台大量使用板级文件如arch/arm/mach-xxx/board-xxx.c来描述硬件资源。这种方式存在明显问题硬件信息与内核代码耦合严重每更换一块板子就要修改内核源码内核镜像无法在不同硬件平台间复用社区维护成本高代码冗余。设备树Device TreeDT的出现解决了上述问题。它将硬件描述从内核源码中剥离出来以独立的数据结构描述 CPU、内存、外设、中断、GPIO 等资源。内核启动时解析设备树动态匹配驱动实现「一套内核多种硬件」的目标。3. 设备树基础语法设备树文件通常以.dtsDevice Tree Source为后缀经过dtc工具编译为.dtbDevice Tree Blob二进制文件供内核解析。3.1 基本结构一个最简单的设备树节点如下/dts-v1/; / { compatible vendor,board-name; model My ARM Board; chosen { bootargs consolettyS0,115200; }; memory80000000 { device_type memory; reg 0x80000000 0x10000000; }; led { compatible myvendor,led; reg 0x40000000 0x10; interrupts GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH; }; };3.2 关键属性说明compatible驱动与设备匹配的关键字符串格式为厂商,型号reg描述设备寄存器地址与长度格式为地址 长度interrupts描述中断号、触发类型status可设为okay或disabled控制设备是否启用。4. 设备树与驱动的匹配机制Linux 内核中驱动通过of_match_table与设备树节点进行匹配。当设备树中某个节点的compatible属性与驱动注册的匹配表一致时内核便会调用驱动的probe函数。staticconststructof_device_idled_of_match[]{{.compatiblemyvendor,led},{/* sentinel */}};MODULE_DEVICE_TABLE(of,led_of_match);staticstructplatform_driverled_driver{.probeled_probe,.removeled_remove,.driver{.namemy-led,.of_match_tableled_of_match,},};module_platform_driver(led_driver);5. 基于设备树的 ARM 驱动开发实战下面以 LED 驱动为例演示从设备树到驱动的完整流程。5.1 设备树节点定义led: led40000000 { compatible myvendor,led; reg 0x40000000 0x10; interrupts GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH; status okay; };5.2 驱动端获取资源在probe函数中通过设备树 API 获取寄存器地址、中断号等资源staticintled_probe(structplatform_device*pdev){structresource*res;structled_dev*dev;devdevm_kzalloc(pdev-dev,sizeof(*dev),GFP_KERNEL);if(!dev)return-ENOMEM;/* 获取寄存器地址 */resplatform_get_resource(pdev,IORESOURCE_MEM,0);dev-regsdevm_ioremap_resource(pdev-dev,res);if(IS_ERR(dev-regs))returnPTR_ERR(dev-regs);/* 获取中断号 */dev-irqplatform_get_irq(pdev,0);if(dev-irq0)returndev-irq;platform_set_drvdata(pdev,dev);return0;}5.3 设备树 API 常用函数函数作用of_property_read_u32()读取 32 位整数属性of_property_read_string()读取字符串属性of_get_named_gpio()获取 GPIO 编号irq_of_parse_and_map()解析中断并映射platform_get_resource()获取寄存器资源6. 学习心得与常见坑点6.1 心得总结设备树本质是「数据驱动」思想驱动代码与硬件描述解耦可移植性大幅提升掌握compatible匹配机制是理解设备树驱动的核心多读内核源码中的Documentation/devicetree/bindings/目录是学习设备树规范的最佳途径。6.2 常见坑点compatible字符串拼写不一致导致驱动无法匹配reg属性地址与芯片手册不一致导致ioremap失败忘记在设备树中设置status okay设备被内核跳过中断号配置错误导致request_irq失败。7. 总结设备树是嵌入式 Linux 驱动开发中不可或缺的一环。通过本文的学习我们从设备树的语法、匹配机制到实际驱动编写建立了一个完整的知识框架。后续可以进一步深入设备树 overlays、pinctrl 子系统、GPIO 子系统等内容逐步构建更扎实的嵌入式驱动开发能力。