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 属性定义地址空间。
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 属性正确映射。
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 为 DTSdtc -I dts -O dtb -o output.dtb input.dts— 编译 DTS 为 DTBfdtdump 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 表示通道编号 |