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 控制器的连接。
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>。
3.2.3 interrupts 属性
interrupts 属性描述设备的中断请求线,其格式由父节点或 interrupt-parent 指定的中断控制器决定。通常包含中断号、中断触发类型等字段。
| 中断类型 | 编码 | 说明 |
|---|---|---|
| IRQ_TYPE_EDGE_RISING | 1 | 上升沿触发 |
| IRQ_TYPE_EDGE_FALLING | 2 | 下降沿触发 |
| IRQ_TYPE_LEVEL_HIGH | 4 | 高电平触发 |
| IRQ_TYPE_LEVEL_LOW | 8 | 低电平触发 |
中断属性示例:
// 中断控制器定义
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 解析节点,获取寄存器地址、中断号、通道数量、传输类型等关键参数。
3.4 常见设备树属性速查表
| 属性 | 用途 | DMA 相关典型值 |
|---|---|---|
compatible | 驱动匹配 | "ti,edma3", "snps,dw-axi-dmac" |
reg | 寄存器地址 | <0x1e000 0x1000> |
interrupts | 中断描述 | <0 12 4> |
dma-channels | DMA 通道数 | <8> |
#dma-cells | DMA 请求描述符大小 | <1> 或 <2> |
dma-requests | 硬件 DMA 请求线数量 | <32> |
实战要点:编写 DMA 控制器设备树节点时,务必确认
#dma-cells 的值与驱动期望一致,否则客户端设备无法正确请求 DMA 通道。