1. DMA 基础概念

1.1 DMA 的定义

DMA(Direct Memory Access,直接存储器访问) 是一种允许硬件设备(如磁盘控制器、网卡、声卡、图形加速器、摄像头接口等)在 不经过 CPU 参与 的情况下,直接与系统内存进行批量数据传输的硬件机制。DMA 控制器(DMAC)作为系统总线上的独立主控设备,接管总线控制权,完成从源地址到目的地址的数据搬运,搬运完成后通过中断通知 CPU。

核心要点: DMA 的本质是“硬件搬运工”——CPU 只需告诉 DMA 控制器“从哪里搬、搬到哪里、搬多少”,然后 DMA 控制器自动完成传输,CPU 可以并行执行其他任务。

1.2 DMA 与 CPU 数据传输的区别

传统的数据传输方式(PIO,Programmed I/O)由 CPU 逐字或逐字节地从外设读取数据到寄存器,再写入内存。DMA 方式则将这一过程完全卸载给专用硬件。下表从多个维度对比两种方式:

对比维度 PIO(CPU 直接传输) DMA(直接存储器访问)
CPU 参与程度 全程参与,逐字搬运 仅初始化配置,传输过程不参与
总线占用 CPU 持续占用系统总线 DMA 控制器占用总线,CPU 可访问 Cache 或执行非内存密集型指令
传输速率 受限于 CPU 时钟和指令吞吐量 接近内存/外设接口的硬件极限带宽
CPU 利用率 传输期间 CPU 100% 被占用 CPU 利用率接近 0%(传输期间)
适用数据量 小数据量(< 64 字节) 大数据量(≥ 64 字节,典型为 KB/MB 级)
实时性影响 阻塞 CPU,影响中断响应 不阻塞 CPU,中断仅在传输完成时触发
硬件复杂度 无需额外硬件 需要 DMA 控制器、描述符表、中断控制器配合
经验法则: 在嵌入式 Linux 驱动开发中,对于每次传输超过 64 字节的外设(如 SPI 帧、I2C 批量数据、UART 大包、MMC 块数据),几乎总是应该使用 DMA 而非 PIO。PIO 仅适合寄存器级别的状态查询或极短的控制帧。

1.3 DMA 传输的优势

DMA 传输带来的核心优势可以归纳为以下四点:

  1. CPU 卸载(Offloading): CPU 从繁重的数据搬运中解放出来,可以执行协议栈处理、任务调度、算法计算等更有价值的工作。
  2. 高吞吐量(High Throughput): DMA 控制器通常以硬件状态机运行,能够以总线时钟频率连续传输,消除 CPU 取指、译码、执行的开销。
  3. 低延迟(Low Latency): 对于批量传输,DMA 的启动延迟(通常几十个总线周期)远低于 CPU 逐字搬运的累积延迟。
  4. 功耗优化(Power Efficiency): CPU 在 DMA 传输期间可以进入低功耗状态(如 WFI/WFE),显著降低系统功耗,这对电池供电的嵌入式设备至关重要。

1.4 典型应用场景

DMA 在嵌入式 Linux 系统中无处不在,以下是几个最典型的应用场景:

  • 存储子系统: eMMC/SD 卡/NAND Flash 控制器使用 DMA 搬运块数据(512B ~ 4KB 每块),避免 CPU 逐块拷贝。
  • 网络子系统: 以太网 MAC 控制器通过 DMA 将接收到的网络帧直接送入内存 Ring Buffer,CPU 只处理协议解析。
  • 多媒体处理: 摄像头传感器通过 DMA 将图像帧(如 1080p YUV 数据,每帧约 3 MB)直接传输到显存或系统内存。
  • 音频子系统: I2S 控制器使用 DMA 循环搬运音频样本,实现低延迟的播放/录音。
  • 高速串行接口: SPI、UART、I2C 在高速模式(SPI 时钟 > 10 MHz)下依赖 DMA 避免 FIFO 溢出。

1.5 DMA 系统架构图

下图展示了一个典型的嵌入式 SoC 中 DMA 控制器与 CPU、内存、外设之间的连接关系:

DMA 系统架构图 DMA 系统架构图(嵌入式 SoC 视角) CPU 核心 (ARM / RISC-V / x86) 系统内存 (DDR / SRAM) DMA 控制器 (DMAC) 以太网 MAC (网络) eMMC 控制器 (存储) I2S 控制器 (音频) SPI 控制器 (高速串行) 配置 / 启动 数据搬运 DMA 请求 DMA 应答 传输完成中断 说明:CPU 通过配置寄存器启动 DMA 传输;DMA 控制器在系统总线上作为主设备直接读写内存和外设 FIFO; 传输完成后通过中断通知 CPU。CPU 在传输期间可执行其他任务或进入低功耗模式。

1.6 DMA 传输的基本流程

一个典型的 DMA 传输过程包含以下步骤,可以用一个简洁的流程图表示:

DMA 传输基本流程 DMA 传输基本流程 ① CPU 配置 DMA 描述符 ② CPU 启动 DMA 通道 ③ DMA 控制器自动搬运数据(CPU 并行工作) ④ DMA 发送完成中断
常见误区: 初学者常误以为 DMA 传输“不需要 CPU”。实际上,DMA 传输的 初始化阶段 必须由 CPU 完成——CPU 需要设置源地址、目的地址、传输长度、传输方向(内存→外设 或 外设→内存)以及触发方式。传输完成后,CPU 还需要在中断处理函数中检查状态并启动下一轮传输(对于循环 DMA 模式则无需重启)。

1.7 本章小结