1. DMA 基础概念
1.1 DMA 工作原理
DMA(Direct Memory Access,直接存储器访问)是一种允许硬件子系统直接读写系统内存的机制,无需 CPU 参与数据搬运。DMA 控制器(DMAC)作为独立的总线主控设备,在系统总线上与 CPU 并行工作,完成内存与外设、内存与内存之间的数据块传输。
核心要点:DMA 的本质是“CPU 委托搬运”——CPU 只需配置传输参数(源地址、目的地址、长度、方向),然后由 DMA 控制器独立完成数据搬运,传输完成后通过中断通知 CPU。
DMA 传输的典型流程分为三个阶段:
- 配置阶段:CPU 设置 DMA 控制器的源地址寄存器、目的地址寄存器、传输长度寄存器、传输方向及触发方式。
- 传输阶段:DMA 控制器获得总线控制权,按配置参数在源与目的之间搬运数据,CPU 可同时执行其他指令。
- 完成阶段:传输计数器归零后,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 的优势在批量数据场景(如音频采样、网络包收发、摄像头帧捕获)中才充分体现。
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 请求信号)
• 传输数据量极小(< 64 字节),DMA 配置开销超过传输收益
• 实时性要求极高且不可容忍仲裁延迟(如某些控制环路)
• 硬件平台缺乏 Cache 一致性支持,导致数据一致性问题难以解决
• 外设不支持 DMA 握手协议(无 DMA 请求信号)
DMA 传输的局限性
- 配置开销:每次 DMA 传输需要设置多个寄存器(源地址、目的地址、长度、控制字),对于极短传输,配置时间可能超过传输时间本身。
- 总线仲裁延迟:DMA 控制器需要向总线仲裁器申请总线控制权,在多主设备系统中可能产生等待周期。
- Cache 一致性问题:DMA 直接访问物理内存,如果 CPU 缓存中存在脏数据,会导致数据不一致。需要软件执行 cache flush/invalidate 操作,或依赖硬件一致性协议(如 ARM 的 ACE/CHI)。
- 描述符管理复杂度:高级 DMA 支持链表描述符(scatter-gather),描述符的构建和管理增加了驱动开发复杂度。
- 中断延迟敏感:DMA 完成中断的响应延迟会影响整体吞吐量,尤其在高速流式传输中需要精心设计中断处理策略。
课程关联提示:在后续章节中,我们将深入设备树中 DMA 控制器的绑定方式(dmas/dma-names 属性)、DMA 引擎驱动框架(dmaengine API)、以及如何通过设备树调试 DMA 通道分配和传输性能瓶颈。本章的基础概念是理解后续所有实战内容的前提。