☰
DMA方式详解:从计算机组成原理考点到嵌入式实战应用
2026/10/1 7:10:41 网站建设 项目流程

如果你正在备考计算机408,或者正在学计算机组成原理这门课,那“I/O设备与主机进行信息传送的控制方式”这一节,基本是必考的重点。而在这一节里,DMA方式又是重中之重。不管是选择题、大题,还是后面的综合应用题,DMA都能穿插进来出题。更重要的是,DMA不是一个只在试卷上出现的概念,它在真实的嵌入式开发、存储系统设计里,几乎是底层数据搬运的“默认答案”。

这篇内容我就结合教材上的经典知识点,再加上我实际工作中用DMA搬运数据的一些体会,把DMA方式从原理到工作流程,再到和中断方式的对比,一次说透。准备考408的同学可以把它当作复习提纲用,刚开始接触计算机组成原理的读者,也能通过这篇文章建立起对DMA的完整认知。

1. DMA方式的核心作用与设计思路

1.1 为什么有了中断方式还不够

在讲DMA之前,得先回顾一下I/O设备与主机之间传送信息的几种控制方式。它们的演进逻辑其实非常朴实:从“CPU全程盯着”到“CPU干别的事,设备好了再通知CPU”,再到“CPU连通知都不用管,设备自己把数据搬完”。

  • 程序查询方式:CPU不断读取设备状态,设备没准备好就一直等。这种方式下CPU基本啥也干不了,效率极低。
  • 中断方式:设备准备好之后向CPU发中断请求,CPU暂停当前程序去处理数据传送。这种方式解决了CPU“死等”的问题,但每次中断都要保护现场、恢复现场,传送一个字节就要中断一次,频繁中断的开销非常大。
  • 缺点很直接:如果一次要传送大量数据,比如从磁盘读一块几KB的数据到内存,如果每个字节都靠CPU来搬,CPU会被中断请求淹没。

这时候就需要一种方式,让CPU把数据搬运这件事“外包”出去,自己只负责发起和收尾。这就是DMA方式的价值所在。

1.2 DMA的实质:让硬件来搬运数据

DMA的全称是Direct Memory Access,直接存储器存取。它的核心思想是:在主存和外设之间开辟一条直接的数据通路,由专门的硬件——DMA控制器——来负责数据的批量搬运。CPU只需要参与传送前的准备工作和传送结束后的收尾工作,传送过程中CPU可以干别的事。

这里要注意,“直接”两个字是关键。中断方式里,数据是“外设→CPU寄存器→主存”的路径。而DMA方式里,数据是“外设→主存”的直接路径,CPU完全不用碰数据本身。

打个比方:公司要给客户发一批重要文件。中断方式相当于每次发一个文件都要让老板亲自去送一趟,老板忙得团团转;DMA方式相当于老板请了一个专职快递员,把整批文件打包交给他,快递员自己一趟趟送完,送完再跟老板说一声。老板只需要安排任务和验收结果就行。

1.3 DMA出现之后解决了哪些实际问题

早期计算机系统里,CPU的性能和外设的速度差距没有那么大。但随着存储设备容量越来越大、外设速度越来越快,CPU如果亲自参与每一次数据搬运,整体性能会被严重拖累。DMA方式的出现,带来三个明显的改善:

  • 减轻CPU负担:数据搬运由DMA控制器完成,CPU可以专注于数据处理、计算等更重要的任务。
  • 提高数据传输速率:DMA的硬件逻辑可以实现高速、连续的传输,不用像中断方式那样反复进行断点保护和恢复。
  • 支持块级传输:DMA一次能传送一个数据块,适合磁盘、网卡、显示设备这类按块传输的外设。

这些特性让DMA成为高性能计算的基石。我们现在用手机拍照、录视频,其实背后都是DMA在帮忙把摄像头传感器里的图像数据搬到内存,否则CPU光处理这些数据量就能被消耗殆尽。

2. DMA控制器的组成结构与传送机制

2.1 DMA控制器内部到底有哪些部件

DMA控制器是DMA方式的核心硬件。它要完成数据搬运,必须有几个基本的部件来记录“搬了多少”“从哪里搬到哪里”“什么时候搬完”。

一个典型的DMA控制器包括以下几个关键部分:

  • 内存地址寄存器(AR):存放要访问的主存单元的地址。传送前由CPU写入起始地址,每传送一个数据就自动加1,指向下一个主存单元。
  • 字计数器(WC):记录要传送的数据块的字节数或字数。每传送一个数据就自动减1,减到0时表示传送完成,向CPU发出中断请求。
  • 数据缓冲寄存器(DBR):用于暂时存放从外设读出的数据,或准备写入外设的数据,起到缓冲作用。
  • 设备选择电路:识别DMA请求来自哪个外设。
  • 中断逻辑:传送完成后向CPU发出中断请求,通知CPU进行后续处理。
  • 控制逻辑:协调上述各部件的工作,生成读写控制信号。

这些部件协同工作,让DMA控制器成为一个“会搬运数据的微型处理器”。它不需要CPU指挥每一步,而是按照预设好的参数自主完成传送。

2.2 DMA传送与主存访问的三种工作方式

DMA控制器要和CPU共用主存,但两者都可能同时想访问主存,这就产生了冲突。怎么解决这个冲突?教材里给出了三种方式,这几乎是考研的选择题、简答题的“常驻嘉宾”。

第一种是停止CPU访问主存。这种方式很“霸道”——DMA请求到来时,DMA控制器会让CPU放弃对地址总线、数据总线和控制总线的控制权,CPU在整个数据块传送期间完全不能访问主存。优点是控制简单,适合高速外设的批量传送;缺点是CPU在这段时间基本闲置,即使它不需要访问主存也无法工作,系统性能受影响比较大。

第二种是周期挪用,也叫周期窃取。DMA控制器只在CPU不访问主存的时间间隙里,偷偷插入一个主存访问周期来完成数据传送,传送完立即把总线控制权交还给CPU。优点是CPU基本不受影响,利用率高;缺点是需要比较复杂的时序控制逻辑,优先级处理不好容易出问题。

第三种是DMA与CPU交替访问。这种方式把主存访问周期一分为二,前半个周期分配给CPU,后半个周期分配给DMA。CPU和DMA各用自己的时隙,从硬件设计上就避开了冲突。优点是完全不需要仲裁逻辑,缺点是主存访问周期被强制拉长,对主存速度要求高,实际使用不算普遍。

这三种方式之间的取舍,本质上就是“效率”和“复杂度”的权衡。备考的时候可以画一个表格来对照记忆,把每种方式的优点、缺点、适用场景写清楚,今年考到理论题也就不怕了。

2.3 DMA传送的基本流程

DMA一次完整的传送过程可以分成三个阶段:传送前预处理、数据传送、传送后处理。很多人在初学的时候容易混淆“CPU到底参与了哪个阶段”,我在这里把三个步骤拆开讲:

预处理阶段由CPU完成,主要动作是:向DMA控制器写入主存起始地址、传送的字数、设备地址、传送方向(读还是写),然后启动外设。这些参数写完之后,CPU就可以切走去做自己的任务了。

数据传送阶段由DMA控制器自动完成。它的工作过程是:外设发出DMA请求,DMA控制器向CPU申请总线控制权,获得总线后,建立外设到主存或主存到外设的直接通路,每次向主存传送一个字或一个字节,同时修改地址寄存器和字计数器,直到整个数据块传送完毕。

后处理阶段:字计数器减到0时,DMA控制器向CPU发出中断请求,CPU响应中断后执行中断服务程序,对传送结果进行校验、检查是否正确、处理后续操作。

这里要特别记清楚一个点:DMA控制器是在数据块传送完成后才发中断,而不是每传一个字就发一次中断。这正是DMA能大幅降低中断开销的原因。也正因为传送过程中CPU完全不需要干预,所以CPU在启动DMA后可以去执行其他程序,等DMA完成后通过中断信号提醒CPU回来做后续处理。

3. DMA与其他I/O控制方式的深度对比

3.1 DMA和中断方式的本质区别

很多初学者把DMA和中断混在一起,觉得“DMA传送完也会发中断,所以DMA就是中断的一种”。这个理解是错的。用一句话概括:中断方式下数据经过CPU搬运,DMA方式下数据不经过CPU。

具体来说,中断方式的每一步数据传送都需要CPU执行专门的指令,从I/O端口读数据到寄存器,再从寄存器写入主存。这意味着CPU必须参与每一个字节的搬运,中断仅用来告诉CPU“可以开始搬了”。DMA方式则不同,CPU只需设置好DMA控制器的参数,真正的数据搬运由DMA控制器用硬件逻辑完成,CPU在传送过程中完全不碰数据。

另一个核心区别是传送单位。中断方式通常以字节或字为单位,每传送一个单位就发生一次中断。DMA方式以数据块为单位,整个数据块传送完成后才发一次中断用于通知CPU做收尾。单位不同,带来的是中断频率和CPU介入程度的巨大差异。

3.2 三种主要I/O控制方式的横向对比

把程序查询方式、中断方式和DMA方式放在一张表里,可以清晰看出它们在数据路径、CPU参与度、传输单位、适用场景上的差异:

对比维度程序查询方式中断方式DMA方式
数据传送路径外设→CPU→主存外设→CPU→主存外设→主存(直接通路)
CPU参与程度全程参与,不断查询状态每个字节/字传送都参与仅在预处理和后处理阶段参与
数据传送单位字节/字字节/字数据块
中断频率无中断每传送一个字节/字中断一次每传送一个数据块中断一次
CPU能否执行其他程序不能能(但频繁被打断)能(基本不受干扰)
适用设备低速设备,如键盘中速设备,如打印机、串口高速设备,如磁盘、网卡、显示设备

这个表格值得你在复习时反复看。选择题如果考到“以下哪种方式传送数据不经过CPU”,答案自然是DMA方式。

3.3 一个数据传送的实例对比

假设外设要向主存传送一个4096字节的数据块,每次从外设读一个字(2字节)。对比一下中断方式和DMA方式的差别:

中断方式下,CPU每收到一次中断就处理两个字节,完成全部传送需要产生和处理2048次中断。每一次中断都涉及保护现场、执行中断服务程序、恢复现场,这个开销即使按几十个时钟周期算,也是相当可观的。更麻烦的是,CPU在处理中断期间不能执行用户程序,频繁的中断会让系统效率变得很差。

DMA方式下,CPU只需要在开始时向DMA控制器写入起始地址、传送字数等参数,然后DMA控制器自动完成2048次数据传送,传送完成后只会产生1次中断。也就是说,同样的数据量,DMA方式的中断次数只有中断方式的1/2048。这个差距就是DMA最大的优势来源。

3.4 DMA和通道方式的简单辨析

在继续深入DMA之前,顺带提一下通道方式。有一部分教材会讲I/O通道控制方式,有些同学会问DMA和通道有什么区别。简单说,通道是比DMA更高级的I/O控制硬件,它本身就是一个专用的I/O处理器,可以执行通道程序,实现更复杂的I/O控制。而DMA控制器只能完成固定的数据搬运工作,功能相对单一。考研中通道方式出题频率不如DMA高,但两者常常放在一起对比,了解即可。

4. DMA的完整工作流程与实操级原理解析

4.1 DMA读操作(外设数据传送到主存)的完整步骤

DMA读操作的完整流程可以用下面这个步骤序列来理解。假设我们要把磁盘缓冲区中的数据读入主存:

第一步,CPU执行几条指令来初始化DMA控制器,包括:向DMA控制器写入主存起始地址、传送的字数、设备地址和操作命令(这里是“读”),之后CPU继续执行主程序。

第二步,外设准备好数据后,向DMA控制器发出DMA请求信号。DMA控制器收到请求后,向CPU发出总线请求信号,请求CPU让出总线控制权。

第三步,CPU完成当前总线周期后,向DMA控制器发出总线允许信号,同时让出总线的控制权。DMA控制器获得总线控制权后,向外设发出DMA响应信号,外设收到响应后把数据放到数据总线上。

第四步,DMA控制器把数据总线上的数据写入主存的指定地址单元,然后将内存地址寄存器加1,字计数器减1。如果字计数器不为零,继续传送下一个数据;如果减到零,说明数据块传送完成。

第五步,DMA控制器释放总线控制权,将总线还给CPU。同时向CPU发出中断请求,CPU响应后执行中断服务程序,进行数据校验和后续处理。

这个流程图的每一步都对应DMA控制器内部电路的时序操作。看起来步骤很多,但在硬件层面上,第四步是循环执行的,速度非常快。

4.2 DMA写操作(主存数据传送到外设)的完整步骤

DMA写操作的过程方向与读操作相反,但仍然包括三个阶段。初始化时CPU向DMA控制器写入主存起始地址、传送字数、设备地址和“写”命令,CPU继续去执行主程序。DMA控制器获得总线控制权后,从主存的指定地址单元读出数据,放到数据缓冲寄存器中,再通过数据总线写入外设。同样每传送一个字就修改地址和字计数,直到整个数据块发送完毕,最后发出中断请求让CPU处理。

在指挥DMA控制器进行写操作时,要注意外设是否处于“准备好接收”的状态。实际硬件中写操作相对读操作有一个“握手确认”的环节:DMA控制器不仅要访问主存,还要确保外设已经就绪。如果外设速度慢,DMA控制器可能需要插入等待周期,这就是为什么DMA虽然叫“直接访问”,但数据传送速率还受限于慢速设备侧的原因。

4.3 DMA传送的时序与总线控制权交接

DMA传送过程最关键的时刻,就是总线控制权的交接。这个交接过程由一组请求和响应信号协作完成:

  • 外设向DMA控制器发送DMA请求信号,表示“我这边有数据要送/我准备好接收数据了”。
  • DMA控制器向CPU发送总线请求信号,相当于“我要用总线,能不能让一下”。
  • CPU在结束当前总线周期后,向DMA控制器发送总线允许信号,表示“当前周期结束,总线归你”。从此刻起,总线控制权从CPU转到DMA控制器手中。
  • 在DMA控制总线期间,CPU如果又要访问主存,必须等待。如果是周期挪用方式,则DMA只在CPU不用总线的空隙插入传送,互不干扰。
  • 数据传送完成后,DMA控制器撤销总线请求信号,把总线控制权交还给CPU。CPU随后可以继续正常访问主存。

这个交接过程反映了一个基本原理:总线同一时间只能由一个主设备控制。要么是CPU,要么是DMA控制器,不可能同时访问主存。这也是为什么DMA的三种工作方式本质都是在解决“谁用了总线、用多久、什么时候交还”这个调度问题。

4.4 DMA控制器内部的一个具体工作实例

有些同学会觉得寄存器、计数器这些概念太抽象,我干脆给一个具体的数字例子。假设我们要把主存地址8000H开始的1024个字传送到外部设备,DMA控制器的工作过程是这样的:

传送前,CPU把起始地址8000H写入内存地址寄存器AR,把传送字数1024写入字计数器WC,把外设地址写入设备选择电路,操作命令设为“写”。启动DMA后,DMA控制器每传送一个字,AR自动加1指向下一个地址,WC自动减1。

当传送过程进行到第500个字时,AR的内容是8000H+499=8333H,WC的内容是1024-499=525。传送完成后,WC变为0,AR变为8333H+1=8334H(有的实现会停在最后一个地址上,考点上并不统一,以教材为准)。这时候WC=0触发中断逻辑,DMA控制器向CPU发出中断请求,CPU响应后进入中断处理程序。

这个例子看起来简单,但考场上如果出这类计算题,最容易出错的就是地址计数器的值到底是“最后一个传送的地址”还是“最后一个地址再加1”。建议复习时把这两种不同教材的说法都看一遍,再做几道真题就能体会出题者的意图。

5. 408考试中DMA相关的高频考点与答题模板

5.1 选择题高频考点清单

DMA在408选择题中出现频率非常高,主要有几类常考方向:

  • DMA传送的数据路径:外设→主存,不经过CPU。
  • DMA传送的基本单位:数据块。
  • DMA中断时机:整个数据块传送完成之后,而不是每个字传送时都中断。
  • DMA工作方式与总线占用:停止CPU访问主存、周期挪用、DMA与CPU交替访问三种方式的特点。
  • DMA的预处理和后处理分别是做什么的:预处理是CPU写初始参数,后处理是CPU响应中断做校验。
  • DMA适用于哪些设备:高速设备,如磁盘、网卡、显示设备、磁带等。
  • DMA和中断方式的主要区别:CPU是否参与数据搬运。

这类题只要概念清晰,基本是送分题。但要注意表述陷阱,比如题目说“DMA方式传送数据不需要CPU干预”,这个说法其实是不严谨的,因为预处理和后处理阶段CPU都参与了,准确说法是“数据传送过程中CPU不干预”。考试时遇到这种表述要多加小心。

5.2 大题和综合应用题常见的考察角度

408的大题很少只考DMA孤立的知识点,它通常会结合存储器、Cache、中断、总线等知识一起出题。常见的有这么几种组合:

一种是DMA与Cache结合,题目给出Cache命中率、访存次数、块大小等参数,要求计算DMA传输时系统效率的变化。解题时要注意分清楚“CPU访存”和“DMA访存”两个独立的行为。

另一种是DMA与中断结合,给出中断响应时间、传送数据块大小、外设速率,要求计算CPU因I/O操作而花费的时间占比。这类题目的本质是计算CPU利用率,需要把DMA传送期间CPU可并行执行程序和中断后处理的开销分开计算。

还有一种是多设备DMA请求的仲裁,系统中有多个外设同时请求DMA,要求画出优先级排队逻辑或说明优先级的分配原则。通常是高速设备、实时性要求高的设备优先。

综合题最怕的就是概念清楚但计算粗心。我的建议是做题时画时间轴,把CPU操作和DMA操作看成两条并行的时序线,在关键时间点上标注事件,这样不容易漏算。

5.3 易混淆知识点的整理与辨析

我在辅导和答疑过程中,发现有几个错误是同学特别容易反复踩的,在这里单独列出来:

DMA传送完成后中断,不等于“DMA属于中断方式”。DMA最后一步的中断只是通知CPU“我干完了”,数据传送的中枢不是CPU的中断服务程序。

“周期挪用”不是“DMA只有在CPU完全空闲时才能工作”,而是“在CPU不使用主存的间隙插入传送”。CPU可能还在执行不访存的指令,DMA照样可以传送。

DMA方式也不是完全不需要软件支持。端口地址、传送方向、计数初值这些参数,还是需要CPU通过指令写入DMA控制器的寄存器才能生效的,这就是所谓“预处理”阶段。这个阶段丢了,后面的事都做不成。

还有一个易错点:DMA控制器访问主存时,地址是由DMA控制器提供的,不是CPU产生的。主存看到的请求方是DMA控制器,对它来说,DMA控制器就像一个特殊的“CPU”。

6. 不同教材中DMA知识点表述差异与备考策略

6.1 王道单科书与唐朔飞教材的表述差异

408参考教材里,唐朔飞老师的《计算机组成原理》和王道考研辅导书在DMA这部分写法上有一些细微差异,这些差异虽然不影响核心原理,但在答题措辞上需要注意。

唐朔飞的教材对DMA工作方式的分类表述偏向“主存访问周期分配”的角度,强调三种方式的时序特征。王道单科书则更侧重“与中断方式的对比”和“典型例题解析”,把大量篇幅放在应试技巧上。

建议复习时以王道作为主线建立框架,遇到细节性表述(比如AR到底自动加1还是加的是数据位长度)再回到唐朔飞教材里核对原文。两种资料配合使用,既保证知识面完整,又不会错过考试重点。

6.2 复习DMA部分的时间安排与学习方法

DMA这部分如果只看文字概念,很容易“看一遍就懂、做一遍就错”。我建议的复习节奏是这样的:

第一轮(约2天内),跟王道视频或教材把DMA的概念、三种工作方式、完整流程过一遍,重点是建立“CPU只负责首尾,中间由硬件搬运”的核心观念。

第二轮(约3天内),刷王道书上的选择题和大题。每一次错题都要回到“流程图”里定位到底错在哪个环节——是总线交接搞混了,还是传送完成后中断时机理解错了,还是寄存器的作用弄反了。定位到具体环节,修正起来比反复背概念有效得多。

第三轮(冲刺阶段),把DMA与中断、Cache、总线等知识点串联起来整理成一张思维导图,做真题时遇到的DMA题目全部归类整理到这张导图下,考前只看这张图就能快速回顾。

我接触过不少考上名校的同学,他们在复习DMA时都有一个共同习惯:不看答案自己画一遍完整的DMA传送流程图。这件事看起来简单,但只有真正动手画过一遍,才会发现自己对“总线请求、总线允许、DMA请求、DMA响应”这几个信号的先后顺序到底有没有真弄懂。

7. DMA在实际开发中的应用场景与硬件实现

7.1 嵌入式开发中的DMA:STM32与串口、ADC的配合

学计算机组成原理的时候,很多同学会觉得DMA离自己很远,但如果你做嵌入式开发,几乎天天都在跟DMA打交道。以STM32为例,它的DMA控制器支持外设到内存、内存到外设、内存到内存三种传输方式,串口接收数据、ADC连续采样、SPI传输数据,都可以使用DMA来减轻CPU负担。

比如用STM32做ADC连续采样,如果不用DMA,每次转换完成都要触发中断,CPU要去读ADC的数据寄存器,哪怕数据没处理也要跑来跑去。用DMA之后,ADC的数据会自动搬运到内存数组里,CPU只需要在DMA传输完成中断里一次性处理所有采样数据。数据量越大,这个收益越明显。

串口通信里也是如此。传统做法是每收到一个字节就进一次串口中断,在里面读取数据。如果数据量大,中断频率极高,CPU被占满,性能很受影响。改为DMA接收之后,串口数据会连续存入指定缓冲区,直到接收到设定长度的数据或产生空闲中断,CPU才被召唤。这在低功耗嵌入式系统里尤为重要。

STM32的DMA配置有几个关键参数要填:源地址、目标地址、数据宽度(字节/半字/字)、传输方向、缓冲区大小、循环模式开关等。任何一个参数配错,DMA要么不工作,要么搬运出乱码。尤其是数据宽度不匹配的问题,比如外设数据寄存器是16位,内存数组定义成了8位类型,DMA搬运的数据就会错位。这类问题在调试时不太好发现,但理解了原理后,排查思路会清晰很多。

7.2 高速存储与网络场景下的DMA依赖

除了嵌入式单片机,DMA在更大规模的系统里同样无处不在。磁盘控制器和主机之间的数据传输基本都依赖DMA,否则机械硬盘或SSD的吞吐量会把CPU拖垮。网卡收到网络数据包时,也通过DMA直接把数据写入主存中的接收缓冲区,再由协议栈处理,这个过程同样离不开DMA。普通情况下我们根本感知不到这些底层行为,但一旦数据量大起来,DMA就是你上网速度不至于因为CPU瓶颈而掉链子的重要保障。

把它和前面讲的考点联系起来:磁盘和网卡都是高速块设备,单位时间的吞吐量大,中断频率如果太高会淹没CPU;DMA一次搬一个数据块,搬完才中断一次,正好匹配这类设备的特性。

7.3 DMA驱动开发流程的一个简化示例

实际做驱动开发时,DMA的初始化流程和教材里的“预处理-传送-后处理”框架是对应的。用伪代码描述一次从网卡接收数据到内存的DMA流程,大概是这样的:

// 预处理:初始化 DMA 控制器 write_reg(DMA_SRC_ADDR, 网卡FIFO地址); write_reg(DMA_DST_ADDR, 内存缓冲区地址); write_reg(DMA_TRANS_LEN, 数据块字节数); write_reg(DMA_CONTROL, 方向:外设到内存, 使能中断); // 数据传送阶段由 DMA 硬件完成 // 后处理:DMA 完成中断处理函数 if (DMA_ISR & TRANSFER_DONE) { verify_data(); // 校验数据 process_packet(); // 交给协议栈处理 start_next_dma(); // 启动下一轮接收 }

这段流程和教材中的DMA三步工作流程几乎一一对应,理解了教材原理,写驱动时就能快速上手,反过来通过真实场景也能加深对教材内容的理解。所以我一直觉得,学计算机组成原理不能只对着课本读,把原理和实际代码对照起来看,效果是最好的。

7.4 DMA配置时容易踩的硬件级坑

实际使用DMA的过程中,有几个硬件级的坑是新手比较容易踩的,这里一并说一下:

第一,DMA缓冲区要放在能被DMA控制器访问到的内存区域。有些单片机内部有多个RAM区域,不是所有区域都能被DMA访问,配错区域会出现数据搬运完全不动的情况。

第二,DMA传输完成中断里不要做太耗时的事情。虽然DMA大幅减少了中断频率,但DMA完成中断依然是一个中断服务程序,在里面做复杂的数据处理会阻塞CPU响应其他中断,严重的还会丢数据。

第三,循环模式和正常模式要分清。循环模式适合持续的数据流,比如ADC连续采样、麦克风数据采集;正常模式传输完成后就停止了,适合一次性传输。模式选错会导致行为不符合预期。

第四,DMA和Cache之间的一致性。在带Cache的高性能处理器上,如果CPU先写了一块数据要用DMA发出去,需要确保Cache数据先回写主存,否则DMA搬走的可能是主存里的旧数据。这个底层细节在考研中不怎么出现,但在实际开发中碰到一次就够你排查半天的。

8. 常见DMA问题排查思路与学习建议

8.1 学习DMA时的三个“为什么”必须搞清楚

学习DMA这部分,我觉得有三个“为什么”必须彻底搞清楚,不然做题时总会有一种“背了但用不出来”的感觉。

第一个问题是“为什么DMA能提高系统效率”?答案是减少中断次数、减少CPU参与数据搬运的时间。你可以算一笔账:一次中断服务程序需要多少CPU周期,一个数据块如果按字节中断需要多少次,换成DMA之后,这个开销削减了多少倍。算完这笔账,你才会真正理解DMA的意义所在,而不只是记住“DMA效率高”这个结论。

第二个问题是“为什么DMA传送前CPU要设置参数”?因为DMA控制器本身没有智能,它不知道从哪里搬、搬多少、搬到哪,这些信息必须由CPU告诉它。DMA控制器就是个“严格执行命令的搬运工”,没有CPU给它指令,它什么也干不了。

第三个问题是“为什么传送完成后还要发中断”?因为CPU需要知道“搬运完成了”,然后去检查数据是否正确、发起下一次传送。DMA控制器只能完成搬运本身,不能替CPU做决策。如果没有这一步通知,CPU会一直以为搬运动作还在进行中,整个流程就无法闭环。

8.2 排查DMA异常时的常规排查路径

如果你在实际开发中遇到了DMA不工作或者数据错误的问题,可以参考下面这条排查路径,一步一步来:

第一步,确认DMA控制器是否获得了正确的时钟使能。很多MCU的外设默认是关时钟的,DMA控制器也不例外。第一步检查能排除一大批低级问题。

第二步,确认源地址和目标地址是否在DMA可访问的范围内,并且地址对齐是否满足要求。有的DMA要求源和目标的地址对齐方式相同,特别是32位传输时,地址必须4字节对齐,不对齐会导致总线错误。

第三步,确认传输长度配置是否正确。数据宽度是8位还是16位,“长度”的单位是字节还是数据宽度,不同的MCU定义不同,要仔细看寄存器手册。这里出错,表现可能是数据搬了一半就停了或者越界。

第四步,确认中断标志是否正确清除。很多DMA的传输完成中断标志需要软件手动清除,如果没清,下次传输无法触发新的中断,表现就是“DMA只工作了一次就再也不中断了”。

第五步,确认没有和CPU或其他DMA通道抢总线。多个DMA通道同时工作时,优先级设置不对会导致低优先级的DMA长时间得不到响应。

这条排查路径不仅适用于嵌入式开发,理解它的逻辑之后,对理解系统层面的DMA原理也很有帮助。

8.3 关于DMA学习笔记和资源的使用建议

市面上关于计算机组成原理的学习资源很多,王道考研的PDF资料、唐朔飞教材配套的课后习题、白中英老师的教材,还有各种考点总结,质量参差不齐。我的建议是,资料在精不在多,选择一两种主流的作为主线就够了,把精力放在吃透原理和做真题上。

做真题的时候要有意识地将DMA相关题目归类整理。比如把“DMA与中断对比”的题放一组,“DMA传送流程计算”放一组,“DMA与Cache结合”的题放一组,考前复习时按组刷,效率会高很多。光刷零散的题不归类,感觉像是行踪不定的游击战,整理归类后才算系统地构筑巩固。

我自己在实际学习中还有个习惯:用白纸把DMA的完整流程图默画出来,画完之后再对照教材检查。第一次画可能会发现总线请求和DMA请求的顺序画反了、地址寄存器的变化时机搞错了,这些暴露出来的错误正是复习中最宝贵的收获。建议你也试试这个方法。

8.4 一个思想实验:如果把DMA去掉会怎样

为了帮助你真正理解DMA的价值,可以做一个思想实验:假设一台没有DMA的计算机,从磁盘读取一个4KB的数据块到内存。磁盘的扇区大小通常是512字节,4KB就是8个扇区。磁盘每准备好一个扇区的数据,就会向CPU发出一次中断,CPU要把这512字节逐一读入内存。整个过程CPU至少要处理8次中断,搬运4096字节。如果磁盘的读取速度是每秒数百MB,那么每秒钟会产生数以十万计的中断,CPU绝大部分时间都在忙着进中断、出中断,真正用来运行应用程序的时间所剩无几。

而有了DMA之后,同样的4KB数据块,磁盘控制器直接把数据通过DMA控制器搬入内存,CPU只在中途被通知一次“准备开始”和最后被通知一次“已经完成”。CPU在这期间可以编制用户程序任务,执行内存计算,整体系统吞吐量立即上升一个档次。

这个思想实验把DMA的价值变得非常直观:DMA不是为了秀硬件技术而存在的,而是让CPU从繁琐的数据搬运工作中彻底解放出来的刚需设计。

结尾的一点经验分享

DMA这部分内容,从408考研的角度看,它是计算机组成原理里少有的“原理直接对应硬件行为”的知识点。把DMA吃透,不仅考试能拿分,后面学操作系统、学嵌入式、学驱动开发,都会不断和这个概念重逢。

我个人在实际学习中有个体会:千万不要满足于“能看懂”DMA的工作流程。真正的掌握标准是——不看任何资料,自己用一张纸画出完整的DMA传送流程图,讲清楚每个阶段谁在干活、哪些信号在交互、数据从哪里到哪里,再独立把“为什么需要DMA”“DMA与中断的本质区别”两个问题说清楚。如果你能做到这些,DMA这部分基本就稳了。

如果你正在备考408,建议把这个知识点和中断方式、程序查询方式放在一起对比复习,形成完整的I/O控制方式知识网络。如果你是在做嵌入式开发,赶紧去翻一下你手头MCU的DMA例程,用实际运行的现象去验证今天讲的这些原理,收获会比单纯读文章大得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询