1. DMA基础概念:什么是DMA、DMA与CPU数据搬运的区别、DMA在嵌入式系统中的作用

1.1 什么是DMA?

DMA,全称Direct Memory Access,直接存储器访问。说白了,就是硬件自带的一个数据搬运工。

我刚开始接触嵌入式时,总觉得DMA是个很玄乎的东西。后来做项目多了,发现它其实特别朴实——就是一个专门负责搬数据的外设。你给它配置好源地址、目的地址、数据长度,它就能自己吭哧吭哧地把数据搬完,完全不用CPU操心。

核心定义:DMA是一种允许外设直接读写系统内存的硬件机制,数据传输过程不需要CPU参与。

举个例子。你想想看,如果CPU是个项目经理,那DMA就是专门跑腿的实习生。项目经理只需要说一句“把这份文件从A柜搬到B柜”,实习生就能自己搞定。项目经理可以继续干别的活,不用亲自搬文件。

1.2 DMA与CPU数据搬运的区别

这个区别,我当年面试时被问过。其实理解起来不难,咱们从几个维度对比一下:

对比维度 CPU搬运 DMA搬运
执行方式 逐条指令执行,软件控制 硬件自动完成,无需指令
占用资源 占用CPU核心,无法处理其他任务 不占用CPU,可并行处理
传输速度 受限于CPU指令执行速度 接近总线带宽,速度更快
适用场景 小数据量、频繁交互 大数据量、周期性传输
功耗 CPU高负载运行,功耗高 专用硬件,功耗低

我记得有个项目,需要从ADC采集音频数据。一开始用CPU轮询读取,结果CPU占用率飙到80%,系统都快卡死了。后来换成DMA,CPU占用率直接降到5%以下。嗯,这就是差距。

我的经验:判断用CPU还是DMA,有个简单标准——如果一次传输超过几十个字节,或者传输频率很高,果断上DMA。否则,用CPU直接操作反而更简单。

1.3 DMA在嵌入式系统中的作用

DMA在嵌入式系统里,说白了就是解放CPU的利器。我总结了一下,主要有这几个作用:

1.3.1 提升系统吞吐量

CPU不用亲自搬数据了,可以腾出手来处理更重要的任务。比如在视频处理中,DMA负责把图像数据从摄像头搬到内存,CPU专心做图像算法。两者并行工作,系统吞吐量翻倍。

1.3.2 降低CPU负载

这个很好理解。你想想看,如果CPU每秒钟要处理1000次中断,每次中断都要搬几百个字节的数据,那CPU基本就废了。用DMA的话,CPU只需要在传输开始和结束时各处理一次中断,中间全交给DMA。

注意:DMA传输完成后会产生中断。我曾经踩过一个坑——DMA中断服务函数里做了太多事情,导致下一次DMA传输被延迟。后来我养成了习惯:中断里只做最必要的事,比如设置一个标志位,具体处理放到主循环里。

1.3.3 实现低功耗设计

这一点很多新手容易忽略。CPU在运行时要消耗大量功耗,而DMA是专用硬件,功耗低得多。在电池供电的设备中,用DMA代替CPU做数据搬运,能显著延长续航。

1.3.4 支持高速外设

像以太网、USB、SD卡这些高速外设,如果没有DMA,CPU根本跟不上它们的速度。我做过一个项目,SD卡读写速度要求50MB/s,用CPU轮询根本不可能,必须上DMA。

1.4 DMA的工作流程

为了让你更直观地理解,我画了一张DMA传输的流程图:

DMA传输流程图 CPU DMA控制器 内存 外设 ① 配置DMA ② 请求传输 ③ 传输数据 ④ 传输完成中断 ⑤ 处理数据 流程说明: ① CPU配置DMA源地址、目的地址、数据长度 ② 外设发出DMA请求 ③ DMA控制器自动完成数据传输 ④ 传输完成后DMA发送中断给CPU

1.5 实际项目中的DMA应用

我做过一个数据采集系统,需要同时采集8路模拟信号。每路信号采样率10kHz,每次采样16位数据。算下来每秒要处理的数据量是:

8路 × 10kHz × 2字节 = 160KB/s

如果不用DMA,CPU每秒钟要处理8万次中断。每次中断里还要读数据、存数据、更新指针。CPU基本就废了。

用了DMA之后,配置好循环模式,DMA自动把数据搬到内存缓冲区。CPU只需要每秒钟处理一次缓冲区满中断,把数据取走就行。CPU占用率从80%降到了5%。

我的建议:刚开始用DMA时,先从小数据量开始测试。我习惯先传几个字节,确认配置正确了,再加大数据量。这样出了问题好排查。

1.6 本章小结

DMA说白了就是一个硬件数据搬运工。它的核心价值在于:让CPU从繁琐的数据搬运中解脱出来,去做更有价值的事情。

记住三个关键点:

  • DMA是硬件,不是软件——配置好就自己干活
  • DMA和CPU可以并行工作——这才是性能提升的关键
  • DMA适合大数据量、周期性传输——小数据量用CPU反而更简单

下一章我们会深入DMA的硬件架构,看看DMA控制器内部到底长什么样。到时候我会结合一个实际芯片的DMA模块,带你一步步分析。