3. 设备树基础回顾:设备树语法、节点与属性、reg属性、interrupts属性、compatible属性

设备树(Device Tree)是一种描述硬件资源的数据结构,它通过节点(node)和属性(property)的层级关系,将非可枚举的硬件细节传递给操作系统内核。在嵌入式 Linux 中,设备树是 DMA 控制器及其通道配置的载体,也是 DMA Engine 驱动与硬件交互的桥梁。本节将系统回顾设备树的核心语法与关键属性,为后续 DMA 控制器节点编写与驱动解析打下基础。

3.1 设备树基本语法与节点结构

设备树源文件(.dts)采用树形结构,每个硬件设备对应一个节点,节点内包含描述设备特征的属性。节点从根节点 / 开始,通过路径唯一标识。

节点定义格式:
[label:] node-name[@unit-address] {
    [property = value;]
    [child-node {
        ...
    }];
};
  • label:可选标签,用于在其它节点中引用(如 &dma0)。
  • node-name:节点名称,通常为通用设备类型(如 dma-controller)。
  • unit-address:设备在总线上的地址,与 reg 属性第一项对应。
  • 属性:键值对,值可以是字符串、整数、数组、二进制数据或 phandle(指向其它节点的指针)。
提示:设备树中的 phandle 是一种引用机制,通过 <&label> 语法指向另一个节点,常用于 DMA 请求与 DMA 控制器的连接。
设备树节点层级结构 / (根节点) soc@0 dma-controller@1e000 serial@1f000 dma-channel@0 dma-channel@1 节点关系说明 根 → soc → 设备节点 DMA 通道是子节点

3.2 核心属性详解

3.2.1 compatible 属性

compatible 是设备树中最关键的属性,用于将设备节点与内核驱动进行匹配。其值为字符串列表,按优先级从高到低排列,格式为 "厂商,设备型号"。

属性格式示例说明
compatible字符串列表"ti,am335x-edma"厂商前缀 + 设备型号,驱动通过 of_match_table 匹配
reg地址/长度对数组<0x1e000 0x1000>描述设备在总线上的物理地址范围
interrupts中断描述符<0 12 4>中断号、触发类型等,依赖 interrupt-parent
compatible 匹配示例:
// 设备树节点
dma: dma-controller@1e000 {
    compatible = "ti,am335x-edma", "ti,edma3";
    reg = <0x1e000 0x1000>;
    interrupts = <0 12 4>;
};

// 内核驱动匹配表
static const struct of_device_id edma_of_match[] = {
    { .compatible = "ti,am335x-edma", .data = &edma_data },
    { .compatible = "ti,edma3",       .data = &edma3_data },
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, edma_of_match);

3.2.2 reg 属性

reg 属性描述设备在总线上的地址空间,由一组或多组 <地址 长度> 对组成。对于 DMA 控制器,通常描述寄存器基地址和映射范围。

  • 地址:物理地址,位数由父节点的 #address-cells 决定。
  • 长度:地址空间大小,位数由父节点的 #size-cells 决定。
  • 多组 reg:当设备有多个不连续的地址块时,可依次列出。
常见配置:32 位系统中 #address-cells = <1>,#size-cells = <1>;64 位系统中常为 <2> 和 <2>。
reg 属性地址映射示意 系统物理地址空间 DMA 寄存器 0x1E000 - 0x1EFFF reg = <0x1E000 0x1000> DMA 通道寄存器 0x1F000 - 0x1F0FF reg = <0x1F000 0x100> 多组 reg 用于描述不连续的地址块,每组由 (address, length) 构成

3.2.3 interrupts 属性

interrupts 属性描述设备的中断请求线,其格式由父节点或 interrupt-parent 指定的中断控制器决定。通常包含中断号、中断触发类型等字段。

中断类型编码说明
IRQ_TYPE_EDGE_RISING1上升沿触发
IRQ_TYPE_EDGE_FALLING2下降沿触发
IRQ_TYPE_LEVEL_HIGH4高电平触发
IRQ_TYPE_LEVEL_LOW8低电平触发
中断属性示例:
// 中断控制器定义
intc: interrupt-controller@48200000 {
    compatible = "ti,am33xx-intc";
    interrupt-controller;
    #interrupt-cells = <3>;  // 中断域:中断类型、中断号、触发类型
};

// 使用中断的设备节点
dma: dma-controller@1e000 {
    interrupt-parent = <&intc>;  // 引用中断控制器
    interrupts = <0 12 4>;       // 0=SPI, 12=中断号, 4=高电平触发
};
注意:DMA 控制器通常有多个中断输出(传输完成、错误等),需在 interrupts 中按顺序列出,驱动通过索引区分。

3.3 设备树在 DMA 驱动中的角色

设备树为 DMA Engine 驱动提供了硬件拓扑描述,驱动通过 OF(Open Firmware)API 解析节点,获取寄存器地址、中断号、通道数量、传输类型等关键参数。

设备树 → DMA 驱动数据流 设备树节点 compatible / reg / interrupts OF API 解析 of_match_device / of_iomap DMA Engine 驱动 dma_device / dma_chan 典型解析流程 1. of_match_device() 匹配 compatible 获取设备节点 2. of_iomap() / platform_get_resource() 获取 reg 地址 3. platform_get_irq() 获取中断号并注册中断处理 4. of_dma_controller_register() 注册 DMA 控制器到框架

3.4 常见设备树属性速查表

属性用途DMA 相关典型值
compatible驱动匹配"ti,edma3", "snps,dw-axi-dmac"
reg寄存器地址<0x1e000 0x1000>
interrupts中断描述<0 12 4>
dma-channelsDMA 通道数<8>
#dma-cellsDMA 请求描述符大小<1> 或 <2>
dma-requests硬件 DMA 请求线数量<32>
实战要点:编写 DMA 控制器设备树节点时,务必确认 #dma-cells 的值与驱动期望一致,否则客户端设备无法正确请求 DMA 通道。