2. DMA 硬件架构:控制器内部结构、通道与请求线、地址与计数逻辑
DMA 控制器(DMAC)是系统总线上的专用总线主控器,负责在外设与存储器之间搬运数据,无需 CPU 逐字干预。理解 DMAC 的内部结构、通道模型、地址寄存器与传输计数逻辑,是后续调试 Cache 一致性与优化带宽的基础。
2.1 DMA 控制器内部结构
一个典型的 DMA 控制器由以下核心模块组成:
| 模块 | 功能 | 关键寄存器/接口 |
|---|---|---|
| 总线接口单元 | 与系统总线(AHB/AXI/OCP)握手,发起读/写传输 | 地址总线、数据总线、控制信号 |
| 通道控制器 | 管理多个独立 DMA 通道的优先级、仲裁与状态 | 通道使能寄存器、优先级寄存器 |
| 地址生成单元 | 根据源/目的地址寄存器与传输宽度,自动计算下一地址 | 源地址寄存器、目的地址寄存器、地址偏移寄存器 |
| 传输计数逻辑 | 递减剩余传输字节数,到达零时触发中断或链式传输 | 传输计数寄存器、重载寄存器 |
| 请求/应答接口 | 接收外设 DMA 请求(DREQ),返回应答(DACK) | DREQ 线、DACK 线、请求极性寄存器 |
| 中断控制单元 | 传输完成、错误、超时等事件产生中断 | 中断状态寄存器、中断掩码寄存器 |
架构要点: 地址生成单元与传输计数逻辑是 DMAC 的“大脑”——它们决定了数据从哪里来、到哪里去、传多少、传完后做什么。Cache 一致性问题往往出现在地址生成单元对内存区域的访问属性配置错误时。
2.2 DMA 通道与请求线
DMA 通道是 DMAC 内部独立的硬件上下文,每个通道包含一套完整的地址寄存器、计数寄存器和控制寄存器。外设通过请求线(DREQ)向特定通道发起传输请求。
2.2.1 通道模型
- 独立通道:每个通道拥有独立的源地址、目的地址、传输计数和配置。通道之间互不干扰,可同时配置为不同的传输方向。
- 通道仲裁:当多个通道同时请求时,通道控制器根据优先级(固定或轮询)选择下一个获得总线的通道。
- 通道状态:空闲、请求中、传输中、暂停、完成、错误。
2.2.2 请求线映射
请求线是外设与 DMA 通道之间的物理信号连接。常见映射方式:
| 请求线编号 | 典型外设 | 触发条件 | 传输方向 |
|---|---|---|---|
| DREQ0 | UART0 接收 | RX FIFO 非空 | 外设 → 内存 |
| DREQ1 | UART0 发送 | TX FIFO 空 | 内存 → 外设 |
| DREQ2 | SPI0 接收 | RX FIFO 达到阈值 | 外设 → 内存 |
| DREQ3 | I2S0 播放 | DMA 请求(音频帧) | 内存 → 外设 |
| DREQ4 | ADC 转换完成 | 转换结束标志 | 外设 → 内存 |
调试提示: 如果外设 DMA 请求未触发,首先检查请求线是否正确连接到通道,以及外设的 DMA 请求使能位是否置位。使用逻辑分析仪抓取 DREQ 信号是最直接的验证手段。
2.3 源地址与目的地址寄存器
每个 DMA 通道包含两个地址寄存器:源地址寄存器(SAR)和目的地址寄存器(DAR)。它们决定了 DMA 传输的数据来源和目标位置。
2.3.1 地址寄存器配置
- 源地址寄存器(SAR):存放数据源的起始地址。对于外设到内存传输,SAR 指向外设数据寄存器地址;对于内存到内存传输,SAR 指向源内存缓冲区。
- 目的地址寄存器(DAR):存放数据目标的起始地址。对于内存到外设传输,DAR 指向外设数据寄存器地址;对于内存到内存传输,DAR 指向目的内存缓冲区。
2.3.2 地址更新模式
地址寄存器在每次传输后自动更新,更新模式由控制寄存器中的地址增量位决定:
| 模式 | 描述 | 典型场景 |
|---|---|---|
| 固定地址 | 地址不变,每次传输都访问同一地址 | 外设 FIFO 寄存器(如 UART DR) |
| 递增地址 | 地址按传输宽度递增(1/2/4/8 字节) | 内存缓冲区连续读写 |
| 递减地址 | 地址按传输宽度递减 | 栈操作、反向缓冲区 |
| 循环地址 | 地址在指定范围内循环 | 环形缓冲区、音频流 |
Cache 一致性风险: 当 SAR 或 DAR 指向可缓存(Cacheable)内存区域时,DMA 直接访问内存可能绕过 CPU Cache,导致 CPU 看到的数据与 DMA 传输的数据不一致。必须在 DMA 传输前后执行 Cache 维护操作(clean/invalidate)。
2.4 传输计数与控制逻辑
传输计数逻辑是 DMA 传输的“里程表”,它决定了本次 DMA 操作的总数据量以及传输完成后的行为。
2.4.1 传输计数寄存器
- 传输计数寄存器(TC / CNDTR):存放剩余待传输的数据单元数(通常以字节、半字或字为单位)。
- 重载寄存器:在循环传输模式下,当 TC 递减到零时,自动从重载寄存器恢复初始计数值,实现无限循环传输。
2.4.2 传输完成条件
当传输计数寄存器递减到零时,DMAC 产生以下事件之一:
- 触发中断:向 CPU 发送传输完成中断,软件在 ISR 中处理数据。
- 链式传输:自动加载下一个描述符(Descriptor),开始新一轮传输,无需 CPU 干预。
- 循环重载:从重载寄存器恢复计数值,继续传输(适用于音频/视频流)。
- 停止:通道进入空闲状态,等待下一次软件触发。
2.4.3 控制逻辑状态机
DMA 通道控制逻辑通常实现为有限状态机(FSM),主要状态包括:
| 状态 | 描述 | 进入条件 | 退出条件 |
|---|---|---|---|
| IDLE | 通道空闲,等待请求 | 复位或传输完成 | 软件使能 + 外设请求 |
| REQ | 等待总线仲裁授权 | 外设请求到达 | 获得总线控制权 |
| XFER | 正在传输数据 | 总线授权 | 单次传输完成 |
| DONE | 传输完成,产生事件 | TC 递减到零 | 中断处理或链式加载 |
| ERROR | 传输错误(总线错误、超时) | 错误条件触发 | 软件清除错误标志 |
2.5 关键寄存器汇总
以下是一个典型 DMA 通道的寄存器集合,软件通过配置这些寄存器来控制 DMA 传输行为:
| 寄存器 | 缩写 | 位宽 | 功能描述 |
|---|---|---|---|
| 源地址寄存器 | SAR | 32/64 | 数据源起始地址 |
| 目的地址寄存器 | DAR | 32/64 | 数据目标起始地址 |
| 传输计数寄存器 | CNDTR / TC | 16/32 | 剩余传输单元数 |
| 控制寄存器 | CR | 32 | 传输方向、地址模式、中断使能、优先级 |
| 状态寄存器 | SR | 32 | 通道状态、错误标志、完成标志 |
| 请求选择寄存器 | RSR | 32 | 将外设请求线映射到本通道 |
| 重载寄存器 | RLR | 16/32 | 循环模式下自动恢复的计数值 |
工程实践要点:
- 配置 DMA 前,先确保 SAR/DAR 地址对齐到传输宽度(如 4 字节对齐)。
- 传输计数寄存器写入的值是传输单元数,不是字节数。例如传输宽度设为 4 字节,TC=100 表示传输 400 字节。
- 在链式传输中,每个描述符包含独立的 SAR、DAR、TC 和 CR,描述符之间通过 next 指针链接。
- 调试时优先检查 SAR/DAR 是否指向正确的物理地址(非虚拟地址),以及 TC 是否递减到零。