什么是 DMA?
更新时间:2026-09-21。问题驱动短答页。入门见 中断与 DMA,微架构见 DMA 控制器,突发/对齐/一致性见 DMA 突发与 Cache。
一句话回答
DMA(直接存储器访问)让「外设 ↔ 内存」「内存 ↔ 内存」的数据搬运不再由 CPU 逐字节读改写,而是交给 DMA 控制器(DMAC)自动完成:CPU 配好源地址、目的地址、长度后去做别的事,整段搬完 DMAC 再发个中断通知。 高速连续数据(ADC 采样、网卡、磁盘、屏幕刷新)尤其受益。
没有 DMA 会怎样
- 轮询方式:CPU 反复查询就绪标志,全程被占死。
- 逐字节中断:每来一个数据进一次中断,保存/恢复现场的开销在高速率下可能超过搬运本身,CPU 大半时间耗在进出中断。
DMA 把整段搬运变成「初始化一次 → 收尾一次中断」,中间 CPU 可跑其他任务。
关键机制
- 突发(burst)/单次:一次请求连续搬多个 beat,提高总线效率;具体见 DMA 突发与对齐。
- 地址自增/固定:内存侧通常自增,FIFO 外设侧地址固定。
- 通道与优先级/仲裁:多通道并发时谁先用总线。
- 描述符链/scatter-gather:把多段不连续传输串成链表,硬件自动接力(见 描述符环设计)。
最大的坑:Cache 一致性
DMA 直接访问物理内存,绕过 CPU Cache:
- 内存→外设前,若数据还留在 CPU Cache 没写回,DMAC 读到的是旧内存(要 clean/flush)。
- 外设→内存后,CPU Cache 里若有旧行,会读到陈旧数据(要 invalidate)。
带硬件一致性的总线(如 AXI ACE)可自动同步;否则软件必须在合适时机 clean/invalidate,见 DMA 突发、对齐与 Cache 一致性。
常见坑
- DMA 缓冲区仍走 Cache 又不做 clean/invalidate:数据时对时错,极难查。
- 缓冲区没做缓存对齐/地址对齐,或落在可被换出的虚拟内存:要用物理连续、未缓存或正确映射的内存。
- 传输长度/宽度/突发与外设不匹配:丢数据或总线错误。
- 搬完立刻在中断外用数据却没等完成信号:竞争。
- 以为 DMA「零成本」:初始化、描述符、中断仍有开销,只搬一两个字节未必划算。
总结
DMA 用专用控制器在外设和内存间自动搬数据,CPU 只需配置源/目的/长度并在整段完成时收一次中断,从而避免轮询占死 CPU 和逐字节中断的高开销,适合 ADC、网卡、磁盘、显示等高速流;使用要点是用突发提高效率、地址自增/固定按源选择、描述符链支持散列传输,最容易出错的是 DMA 绕过 Cache 导致的一致性问题——发送前 clean、接收后 invalidate(或用硬件一致性总线),并保证缓冲区物理连续且正确对齐。