1. DMA 基础概念

1.1 DMA 工作原理

直接存储器访问(Direct Memory Access, DMA)是一种允许硬件子系统独立于 CPU 直接读写系统内存的机制。在 DMA 传输过程中,CPU 只需初始化传输任务,随后由 DMA 控制器接管数据搬运工作,传输完成后通过中断通知 CPU。

核心思想:将数据搬运从 CPU 卸载到专用硬件,实现 CPU 与 I/O 操作的并行执行。
DMA 传输系统架构 CPU DMA 控制器 系统内存 外设 (I/O) 配置/启动 DMA 传输 内存访问 数据请求 传输完成中断 工作流程 1. CPU 配置 DMA 源/目的/长度 2. DMA 独立搬运数据 3. 传输完成 → 触发中断

1.2 DMA 与 CPU 数据搬运的区别

传统 PIO(Programmed I/O)模式下,CPU 逐字节或逐字搬运数据,完全占用处理器核心。DMA 模式下,CPU 仅参与传输设置和完成处理,数据路径绕过 CPU 核心。

对比维度 CPU 搬运 (PIO) DMA 搬运
数据路径 外设 → CPU 寄存器 → 内存 外设 ↔ 内存(直通)
CPU 占用率 100%(传输期间) 仅初始化 + 中断处理(<5%)
传输粒度 字节/字(软件循环) 块/描述符链(硬件自动)
吞吐量 受限于 CPU 频率 受限于总线带宽
延迟 低(无额外硬件开销) 中等(DMA 引擎启动延迟)
适用场景 小数据量、控制寄存器访问 大数据块、流式 I/O
经验法则:单次传输小于 64 字节时,PIO 可能比 DMA 更高效,因为 DMA 引擎的启动开销超过了节省的 CPU 时间。

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

核心优势

  • CPU 卸载:释放处理器执行应用逻辑,而非数据搬运。
  • 高吞吐量:利用总线突发传输,接近硬件理论带宽。
  • 低延迟抖动:硬件状态机保证确定性传输时序。
  • 支持后台传输:DMA 可与 CPU 缓存/指令流水线并行工作。
  • 描述符链:支持 scatter-gather,无需连续物理内存。

典型适用场景

场景 说明 典型带宽需求
网络数据包收发 网卡 DMA 直接将帧写入内存 Ring Buffer 1 Gbps ~ 100 Gbps
存储设备读写 NVMe/SATA 控制器 DMA 搬运块数据 500 MB/s ~ 14 GB/s
多媒体采集 摄像头/音频 ADC 通过 DMA 填充帧缓冲区 10 MB/s ~ 2 GB/s
GPU 纹理传输 CPU 与 GPU 间通过 DMA 交换顶点/纹理数据 10 GB/s+
FPGA 加速器 自定义硬件通过 DMA 与主机内存交换数据 取决于 PCIe 通道数
DMA 适用场景决策树 数据传输需求 小数据 / 低频 大数据 / 流式 PIO / 寄存器访问 DMA 引擎传输 决策依据:传输块大小 > 256 字节 且 频率 > 1000 次/秒 → 优先选择 DMA

不适用场景

  • 小数据量控制操作:如配置寄存器、读取状态字(通常 < 64 字节)。
  • 非连续随机访问:DMA 对非连续地址的预处理开销较大。
  • 实时性要求极高的短事务:DMA 引擎启动延迟(通常 1~10 μs)可能不可接受。
  • 硬件不支持 DMA 的外设:老旧 UART、GPIO 等。
常见误区:并非所有外设都适合 DMA。如果每次传输前都需要修改传输参数(如动态变长协议头),DMA 的配置开销可能抵消收益。此时应考虑混合模式:小头部用 PIO,大数据载荷用 DMA。

1.4 DMA 传输模式分类

模式 描述 典型应用
单块传输 一次传输一块连续数据,完成后中断 简单 ADC 采样、单帧图像采集
循环缓冲 DMA 在固定缓冲区循环写入,地址自动回绕 音频流、连续数据采集
描述符链 多个 DMA 描述符组成链表,硬件自动加载下一个 网络数据包、存储队列
Scatter-Gather 一次 DMA 操作读写多个非连续内存块 文件系统 I/O、虚拟内存映射
Linux 内核视角:DMA 引擎驱动通过 dmaengine 子系统统一管理,提供 dma_device 抽象层。传输描述符使用 dma_async_tx_descriptor 结构体,支持回调函数和事务提交。