1. DMA 基础概念

1.1 DMA 工作原理

DMA(Direct Memory Access,直接存储器访问)是一种允许硬件子系统直接读写系统内存的机制,无需 CPU 参与数据搬运。DMA 控制器(DMAC)作为独立的总线主控设备,在系统总线上与 CPU 并行工作,完成内存与外设、内存与内存之间的数据块传输。

核心要点:DMA 的本质是“CPU 委托搬运”——CPU 只需配置传输参数(源地址、目的地址、长度、方向),然后由 DMA 控制器独立完成数据搬运,传输完成后通过中断通知 CPU。
DMA 传输系统架构 CPU DMA 控制器 (DMAC) 系统内存 外设 系统总线(System Bus) 图例 DMA 数据路径 控制/配置路径 CPU 配置 DMAC 后 即可并行处理其他任务

DMA 传输的典型流程分为三个阶段:

  1. 配置阶段:CPU 设置 DMA 控制器的源地址寄存器、目的地址寄存器、传输长度寄存器、传输方向及触发方式。
  2. 传输阶段:DMA 控制器获得总线控制权,按配置参数在源与目的之间搬运数据,CPU 可同时执行其他指令。
  3. 完成阶段:传输计数器归零后,DMA 控制器向 CPU 发出中断信号,CPU 在中断处理函数中确认传输完成并回收缓冲区。

1.2 DMA 与 CPU 数据搬运的区别

CPU 搬运数据(PIO 模式)与 DMA 搬运在架构、性能、资源占用上存在本质差异。下表从多个维度进行对比:

对比维度 CPU 搬运(PIO) DMA 搬运
执行主体 CPU 核心(通用寄存器 + 指令流水线) DMA 控制器(专用硬件状态机)
数据路径 外设 → CPU 寄存器 → 内存(两次总线事务) 外设 ↔ 内存(一次总线事务,旁路 CPU)
CPU 占用率 100%(搬运期间 CPU 被完全占用) 仅配置和中断阶段占用(通常 < 5%)
传输速率 受限于 CPU 主频和指令吞吐量 受限于总线带宽和 DMA 引擎频率
适用数据量 小数据块(通常 < 64 字节) 大数据块(通常 > 256 字节)
延迟特性 低延迟(无仲裁开销) 有初始仲裁延迟(通常 10~100 总线周期)
Cache 一致性 天然一致(CPU 直接操作) 需软件维护或硬件一致性协议
硬件复杂度 无需额外硬件 需要 DMA 控制器、中断控制器支持
实战经验:在嵌入式 Linux 驱动中,对于 SPI、I2C 等低速外设的小数据交互(如寄存器读写),PIO 模式反而更优——省去了 DMA 配置和中断响应的固定开销。DMA 的优势在批量数据场景(如音频采样、网络包收发、摄像头帧捕获)中才充分体现。
CPU 搬运 vs DMA 搬运:数据路径对比 CPU 搬运(PIO 模式) CPU 内存 外设 ① 读外设 ② 写内存 两次总线事务,CPU 全程参与 DMA 搬运模式 CPU 内存 外设 DMAC DMA 直接搬运 仅配置阶段 一次总线事务,CPU 可并行执行其他任务

1.3 DMA 传输的优势与适用场景

核心优势

  • CPU 卸载:将数据搬运任务从 CPU 卸载到专用硬件,CPU 可专注于控制逻辑、协议解析和上层应用。
  • 高吞吐量:DMA 引擎通常运行在总线时钟域,可达到接近总线理论极限的传输速率(如 AXI 总线上的 DMA 可达数 GB/s)。
  • 低延迟批量传输:对于大数据块,DMA 的传输延迟远低于 CPU 逐字搬运,且延迟可预测。
  • 支持后台传输:DMA 传输可与 CPU 执行指令完全并行,实现真正的“后台数据搬运”。
  • 减少中断频率:一次 DMA 传输可搬运数千字节,仅产生一次完成中断,而 PIO 模式下每字节或每字都可能触发中断。

典型适用场景

场景 数据特征 DMA 收益 典型速率
音频 I2S 采集/播放 连续流,16/24/32 位采样,双声道 CPU 占用率从 80% 降至 < 5% 48 kHz × 4 字节 × 2 = 384 KB/s
摄像头 MIPI/CSI 帧捕获 突发大块数据,每帧 1~10 MB 避免帧丢失,支持多缓冲区轮转 1080p@30fps ≈ 93 MB/s
以太网 MAC 收发 变长包,64~1518 字节 零拷贝网络栈,减少内存带宽消耗 千兆以太网 ≈ 125 MB/s
SD/MMC 存储读写 块设备,512 字节/块,连续多块 支持 scatter-gather,提高大文件 IOPS eMMC 5.1 ≈ 400 MB/s
SPI 闪存编程 大块写入,256 字节/页 释放 CPU 处理擦除/校验逻辑 SPI 时钟 50 MHz ≈ 25 MB/s
内存到内存拷贝 大缓冲区复制(如视频帧处理) 比 memcpy() 快 2~5 倍(多通道 DMA) 取决于 DMA 通道数和总线位宽
注意:DMA 并非万能方案。在以下场景中应谨慎使用或避免使用 DMA:
• 传输数据量极小(< 64 字节),DMA 配置开销超过传输收益
• 实时性要求极高且不可容忍仲裁延迟(如某些控制环路)
• 硬件平台缺乏 Cache 一致性支持,导致数据一致性问题难以解决
• 外设不支持 DMA 握手协议(无 DMA 请求信号)
DMA 适用性决策树 需要数据搬运? 数据量 > 256 字节? 使用 PIO 模式 小数据量,避免 DMA 配置开销 外设支持 DMA? 回退到 PIO 模式 使用 DMA 传输 配置 DMAC → 启动传输 → 等待中断

DMA 传输的局限性

  • 配置开销:每次 DMA 传输需要设置多个寄存器(源地址、目的地址、长度、控制字),对于极短传输,配置时间可能超过传输时间本身。
  • 总线仲裁延迟:DMA 控制器需要向总线仲裁器申请总线控制权,在多主设备系统中可能产生等待周期。
  • Cache 一致性问题:DMA 直接访问物理内存,如果 CPU 缓存中存在脏数据,会导致数据不一致。需要软件执行 cache flush/invalidate 操作,或依赖硬件一致性协议(如 ARM 的 ACE/CHI)。
  • 描述符管理复杂度:高级 DMA 支持链表描述符(scatter-gather),描述符的构建和管理增加了驱动开发复杂度。
  • 中断延迟敏感:DMA 完成中断的响应延迟会影响整体吞吐量,尤其在高速流式传输中需要精心设计中断处理策略。
课程关联提示:在后续章节中,我们将深入设备树中 DMA 控制器的绑定方式(dmas/dma-names 属性)、DMA 引擎驱动框架(dmaengine API)、以及如何通过设备树调试 DMA 通道分配和传输性能瓶颈。本章的基础概念是理解后续所有实战内容的前提。