3. 设备树基础

设备树(Device Tree)是嵌入式 Linux 中描述硬件拓扑结构的核心机制。对于 ADC 设备驱动开发而言,理解设备树的语法、节点结构以及关键属性(reg、compatible、中断)是正确配置 IIO 驱动与通道绑定的前提。本章将系统讲解设备树的基础知识,并通过 ADC 实例进行实战解析。

3.1 设备树语法与节点结构

设备树采用树形结构描述硬件,每个硬件设备对应一个节点(node),节点内包含若干属性(property)。节点从根节点(/)开始,通过路径唯一标识。

核心语法规则:
  • 节点名称格式:node-name@unit-address,其中 unit-address 通常为设备基地址。
  • 属性格式:property-name = <value>; 或 property-name = "string";。
  • 标签(label):label: node-name@address,用于在其它节点中引用。
  • 包含文件:#include "filename.dtsi",用于复用通用定义。
💡 实战提示:ADC 设备节点通常位于 soc 或 spi / i2c 总线节点下,通过 compatible 属性匹配驱动,通过 reg 属性定义地址空间。
设备树节点层级结构(ADC 设备示例) / (根节点) soc@0 spi@10000000 i2c@20000000 adc@0 (SPI ADC) compatible = "adi,ad7124" adc@48 (I2C ADC) compatible = "ti,ads1015" ADC 设备节点通常挂载在 SPI 或 I2C 总线节点下,通过 compatible 属性匹配驱动

3.2 关键属性详解

3.2.1 compatible 属性

compatible 是设备树中最重要的属性,用于将设备节点与驱动程序绑定。其值为字符串列表,格式为 "厂商,设备型号"。驱动通过 of_match_table 进行匹配。

属性 格式 示例 说明
compatible 字符串列表 "adi,ad7124" 厂商名 + 设备型号,驱动匹配依据
reg 32位整数对列表 <0x10000000 0x1000> 地址 + 长度,描述寄存器空间
interrupts 32位整数列表 <0x1e 2> 中断号 + 触发类型
interrupt-parent phandle <&gpio0> 引用中断控制器节点

3.2.2 reg 属性与地址编码

reg 属性描述设备在总线上的地址空间。对于 SPI 设备,reg 表示片选号;对于 I2C 设备,表示从设备地址;对于内存映射设备,表示基地址和范围。

ADC 设备 reg 属性示例:
// SPI 总线上的 ADC:reg 表示片选 CS0
spi_adc: adc@0 {
    compatible = "adi,ad7124";
    reg = <0>;               // 片选 0
    spi-max-frequency = <5000000>;
};

// I2C 总线上的 ADC:reg 表示从设备地址 0x48
i2c_adc: adc@48 {
    compatible = "ti,ads1015";
    reg = <0x48>;            // I2C 地址 0x48
};

// 内存映射 ADC:reg 表示基地址和范围
mmio_adc: adc@ffc00000 {
    compatible = "xlnx,xadc";
    reg = <0xffc00000 0x1000>;  // 基地址 0xffc00000,范围 4KB
};

3.2.3 中断属性配置

ADC 设备通常使用中断通知 CPU 数据就绪。中断属性包括 interrupt-parent(指定中断控制器)和 interrupts(中断号与触发类型)。

中断触发类型 编码值 说明
IRQ_TYPE_EDGE_RISING 1 上升沿触发
IRQ_TYPE_EDGE_FALLING 2 下降沿触发
IRQ_TYPE_LEVEL_HIGH 4 高电平触发
IRQ_TYPE_LEVEL_LOW 8 低电平触发
⚠️ 常见错误:中断号与 GPIO 号混淆。中断号是中断控制器内部的编号,不是 GPIO 引脚号。使用 GPIO 作为中断源时,需要通过 interrupts-extended 或 gpios 属性正确映射。
ADC 设备中断属性配置流程 ADC 设备节点 adc@0 interrupt-parent 中断控制器 &gpio0 interrupts 中断描述 <0x1e 2> (下降沿) 中断线 CPU 内核 interrupt-parent 指向中断控制器,interrupts 指定中断号和触发类型

3.3 ADC 设备节点完整示例

以下是一个完整的 SPI 总线 ADC 设备节点配置,包含 compatible、reg、中断以及 IIO 驱动所需的通道绑定属性。

// SPI 总线定义
&spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;

    // ADC 设备节点
    adc0: adc@0 {
        compatible = "adi,ad7124";
        reg = <0>;                    // SPI 片选 CS0
        spi-max-frequency = <5000000>;
        interrupts-extended = <&gpio0 30 2>;  // GPIO0_30, 下降沿触发
        #address-cells = <1>;
        #size-cells = <0>;

        // IIO 通道绑定
        channel@0 {
            reg = <0>;                // 通道 0
            label = "vref";
            adi,bipolar = <0>;
            adi,buffered = <1>;
        };

        channel@1 {
            reg = <1>;                // 通道 1
            label = "temperature";
            adi,bipolar = <0>;
            adi,buffered = <1>;
        };
    };
};

3.4 设备树编译与调试

设备树源文件(.dts / .dtsi)需要通过 dtc 工具编译为二进制 .dtb 文件,再由 bootloader 传递给内核。

常用调试命令:
  • dtc -I dtb -O dts -o output.dts input.dtb — 反编译 DTB 为 DTS
  • dtc -I dts -O dtb -o output.dtb input.dts — 编译 DTS 为 DTB
  • fdtdump input.dtb — 以可读格式显示 DTB 内容
  • ls /proc/device-tree/ — 查看内核解析后的设备树
💡 调试技巧:如果 ADC 驱动未加载,首先检查 /proc/device-tree 下是否存在对应节点,然后确认 compatible 字符串是否与驱动中的 of_match_table 完全一致(包括大小写和逗号)。

3.5 本章小结

知识点 关键内容 ADC 应用要点
设备树语法 节点、属性、标签、包含文件 ADC 节点位于总线节点下,使用标签便于引用
compatible 属性 "厂商,设备型号" 字符串匹配 必须与 IIO 驱动中的匹配表一致
reg 属性 地址 + 长度,或片选/从地址 SPI 用片选号,I2C 用从地址,MMIO 用基地址
中断属性 interrupt-parent + interrupts ADC 数据就绪中断,常用下降沿或电平触发
通道绑定 子节点 + reg + 自定义属性 每个通道一个子节点,reg 表示通道编号