1. 课程导入
DMA,全称 Direct Memory Access,直接存储器访问。说白了,就是让外设和内存之间能直接“对话”,不需要 CPU 在中间当传话筒。
我刚开始接触嵌入式时,总觉得 DMA 是个很玄乎的东西。后来调过几块板子才明白——它就是个硬件级别的数据搬运工。你给它配好源地址、目的地址、传输长度,它自己就把活干完了。
1.1 DMA 与 CPU 的数据搬运对比
咱们先看一个最典型的场景:从 UART 接收 1KB 数据。
CPU 搬运模式:
- CPU 每收到一个字节,就触发一次中断
- CPU 进入中断服务函数,把数据从 UART 数据寄存器搬到内存
- 退出中断,继续执行主程序
- 重复 1024 次
DMA 搬运模式:
- CPU 配置好 DMA 通道:源 = UART 数据寄存器,目的 = 内存缓冲区,长度 = 1024
- 启动 DMA,CPU 该干嘛干嘛去
- DMA 硬件自动搬运,每搬一个字节,硬件计数减 1
- 计数到 0,DMA 发一个完成中断给 CPU
你想想看,这中间差了多少次中断开销?1024 次中断 vs 1 次中断。我在项目中遇到过一块板子,CPU 主频只有 72MHz,用 CPU 搬运 4KB 的 ADC 数据,CPU 占用率直接飙到 85%。换成 DMA 后,CPU 占用率降到 5% 以下。
| 对比项 | CPU 搬运 | DMA 搬运 |
|---|---|---|
| CPU 参与度 | 全程参与,每个字节都要处理 | 仅配置和收尾,中间不参与 |
| 中断次数 | 每传输单元一次 | 整批传输一次 |
| 传输速率 | 受限于 CPU 指令执行速度 | 接近总线理论带宽 |
| CPU 利用率 | 低(大量时间花在搬运上) | 高(CPU 可处理其他任务) |
| 适用场景 | 小数据量、随机访问 | 大数据量、周期性传输 |
核心结论:DMA 的本质是用硬件代替软件做数据搬运,释放 CPU 去做更有价值的事。这不是“优化”,而是嵌入式系统架构的必备手段。
1.2 DMA 在嵌入式系统中的角色
DMA 在嵌入式系统里到底扮演什么角色?我个人的理解是——数据管道的自动化阀门。
没有 DMA 的系统,CPU 就像个快递员,每来一个包裹都要亲自签收、登记、入库。有了 DMA,CPU 变成了仓库经理,只需要告诉系统“这批货送到几号库”,然后就可以去处理其他订单了。
具体来说,DMA 在以下几个场景中不可或缺:
- 高速数据采集:ADC 采样率动辄几 MHz,每个样本都中断?CPU 直接挂掉。DMA 批量搬运,CPU 只做数据处理。
- 显示刷新:LCD 显示缓冲区到屏幕的刷新,DMA 自动完成,CPU 只管画图。
- 通信协议栈:以太网、USB、SDIO 等高速接口,数据包收发几乎都依赖 DMA。
- 音频处理:I2S 音频流的持续传输,DMA 保证无间隙播放。
- 存储器操作:Flash 到 RAM 的代码加载、RAM 到 RAM 的数据搬移。
个人经验:我调试过一块基于 STM32F4 的工业采集板,ADC 以 2MHz 采样,每通道 16 位数据,共 8 个通道。如果不用 DMA,CPU 每秒要处理 16M 次中断——这根本不可能。用 DMA + 双缓冲,CPU 每 1ms 才处理一次数据,稳得很。
1.3 DMA 传输的核心要素
一个完整的 DMA 传输,需要明确以下要素:
- 源地址:数据从哪里来(外设数据寄存器、内存地址)
- 目的地址:数据到哪里去(内存缓冲区、外设数据寄存器)
- 传输宽度:每次搬运多少位(8 位、16 位、32 位)
- 传输计数:总共搬运多少次
- 传输模式:单次、循环、乒乓等
- 触发源:什么事件启动一次传输(定时器、外设请求、软件触发)
嗯,这里要注意:传输宽度必须和外设寄存器宽度匹配。我曾经踩过一个坑——把 16 位 ADC 的 DMA 传输宽度配成 8 位,结果数据全乱了,高位字节和低位字节错位,折腾了两天才发现。
1.4 DMA 传输的典型流程
下面这张图展示了 DMA 一次完整传输的流程:
避坑指南:我曾经在配置 DMA 循环模式时,忘记设置缓冲区大小和传输计数的匹配关系。结果缓冲区只有 256 字节,传输计数配了 1024——DMA 直接写穿了缓冲区,把后面的变量全覆盖了。板子跑起来行为诡异,查了两天才定位到。记住:DMA 没有边界检查,它只按你给的地址和计数干活,错了也照干不误。
1.5 DMA 的分类
从架构角度,DMA 主要分两类:
| 类型 | 特点 | 典型芯片 |
|---|---|---|
| 独立 DMA 控制器 | 独立于 CPU 的硬件模块,有专用总线,可同时处理多通道 | STM32 DMA1/DMA2、NXP eDMA |
| 总线主控 DMA | 外设自身具备总线主控能力,可直接发起传输 | USB OTG、以太网 MAC、SD/MMC 控制器 |
独立 DMA 控制器更灵活,可以服务多个外设。总线主控 DMA 效率更高,因为外设直接接管总线。实际项目中,两者经常配合使用。
1.6 小结
DMA 不是什么高深莫测的技术。它就是一块硬件,专门负责在内存和外设之间搬数据。用好 DMA,你的 CPU 就能从繁重的数据搬运中解放出来,去做真正的计算和控制。
记住三个核心点:
- DMA 是硬件数据搬运工,不是 CPU 的替代品,而是 CPU 的助手
- DMA 传输需要明确配置源、目的、宽度、计数、触发源
- DMA 没有边界检查,配置错了后果自负