ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

计算机组成原理DMA方式详解:从408考研到STM32实战

计算机组成原理DMA方式详解:从408考研到STM32实战 1. 从一道45题说起DMA到底在考什么如果你正在啃计算机组成原理尤其是唐朔飞那本教材的课后题大概率会在I/O系统这一章卡住。24年408那道45题考的就是DMA方式下CPU与I/O设备的信息传送控制很多人看完题干的时序图直接懵了——明明CPU已经把总线让出去了为什么还要算“挪用”了多少个存取周期这背后其实藏着DMA最核心的设计哲学数据传送不经过CPU但总线控制权要“借”。DMA全称Direct Memory Access直接存储器访问。它解决的是一个非常朴素的问题当外设比如磁盘、网卡、ADC采集模块需要和主存之间搬运大批量数据时如果还让CPU一条一条执行load/store指令来中转那CPU基本上就废了全耗在搬砖上了。DMA的思路是找一个专门的硬件控制器DMAC让它直接在主存和外设之间开一条数据通道CPU只需要在开始前告诉DMAC“从哪搬到哪、搬多少、搬完告诉我”然后就可以去干别的事了。这篇文章面向的是正在准备408考研的同学以及工作中需要理解STM32 DMA、Linux DMA、SPI DMA、串口DMA这些实际应用的开发者。我会从408考点的角度切入把DMA的三种传送方式、总线占用机制、与中断方式的对比、以及实际配置中的关键参数全部拆开讲清楚。不管你是为了做题还是为了调通一个ADC多通道DMA采集这篇文章都能让你少走弯路。2. DMA方式的核心设计思路拆解2.1 为什么中断方式还不够用要理解DMA为什么被发明出来得先看它的前辈——程序中断方式有什么毛病。中断方式下外设每准备好一个数据单位比如一个字节或一个字就向CPU发一次中断请求。CPU响应中断后执行中断服务程序把数据从I/O接口读到CPU寄存器再写到主存。整个过程CPU都在参与每传一个字都要打断一次主程序。我拿实际数字算一下你就知道有多离谱了。假设磁盘传输速率是4MB/s每次中断处理开销包括保存现场、恢复现场、执行服务程序大约需要20微秒。那么每秒需要产生100万次中断4MB/4B光中断处理就要花掉20秒——CPU一秒都抽不出来干别的。这就是所谓的“中断风暴”在高速外设场景下中断方式直接不可用。DMA的解法很直接既然CPU只是数据搬运的中转站那就把这个中转站去掉。DMAC自己拥有地址总线和数据总线的控制能力可以直接把外设数据写入主存或者把主存数据读出送到外设。CPU只在传送开始前做初始化传送结束后处理一次中断。中间过程CPU完全不参与。2.2 DMA控制器的内部结构长什么样DMAC不是随便一个芯片就能干的它内部需要几个关键部件协同工作。理解这些部件对做题和实际配置都有帮助。主存地址寄存器AR存放当前要读写的主存地址。每传送一个字这个寄存器自动加一或减一指向下一个位置。这就是为什么DMA适合连续数据块传送——地址自动递增不需要CPU干预。字计数器WC记录还剩多少个字没传。每传一个字减一减到零时发出结束信号。这个计数器决定了DMA传送的长度在STM32里对应的就是NDTR寄存器。数据缓冲寄存器BR暂时存放正在传送的数据。外设和主存的速度可能不匹配这个缓冲起到一个缓冲作用。设备地址寄存器DAR存放外设的地址或接口标识用来选中要通信的外设。控制/状态逻辑负责接收CPU的初始化命令、产生DMA请求信号、管理总线占用、在传送结束时发出中断请求。中断机构传送完成后向CPU发中断告诉CPU“活干完了”。这些部件协同工作的流程是CPU初始化AR、WC、DAR和控制寄存器然后启动DMAC。DMAC向外设发出DMA请求外设准备好后给出应答DMAC向CPU申请总线使用权获得总线后直接在内存和外设之间传送数据每传一个字AR和WC更新一次WC归零时触发中断。2.3 DMA与中断方式的本质区别很多人做题时容易把DMA和中断方式搞混因为两者都涉及“打断CPU”。但它们的打断粒度完全不同。中断方式是每传一个数据单位就打断一次CPU需要执行指令来完成数据搬运。DMA方式是整块数据传送只打断两次——开始前初始化一次这甚至不算打断是CPU主动执行的结束后中断一次。中间的数据搬运CPU完全不参与。从数据流向看中断方式的数据路径是外设→CPU寄存器→主存。DMA方式的数据路径是外设→主存或主存→外设CPU被完全旁路。从优先级看DMA请求的优先级高于中断请求。因为DMA请求对应的是数据传送的实时性要求如果DMA请求被中断请求打断可能导致数据丢失。在总线仲裁中DMAC通常拥有比CPU更高的总线优先级。3. DMA三种传送方式停止CPU访存、周期挪用、交替访存这是408考试的高频考点也是实际硬件设计中三种不同的总线占用策略。每种方式对应不同的效率和应用场景理解它们的区别对做题至关重要。3.1 停止CPU访存方式这种方式最粗暴DMAC一旦获得总线控制权就独占总线直到整块数据传送完毕才把总线还给CPU。在DMA传送期间CPU完全无法访问主存只能干等着或者做那些不需要访存的操作比如执行寄存器间的运算。优点是控制简单DMAC只需要在开始时申请一次总线传送过程中不需要反复仲裁。缺点是CPU访存被完全阻塞如果DMA传送的数据块很大CPU的性能损失非常明显。这种方式适合什么场景适合外设数据传输速率极高、且数据块不大的情况。比如某些高速ADC的突发采集采集一批数据就结束CPU等一小会儿可以接受。但如果是一个持续的大文件传输用这种方式CPU基本上就废了。在408题目中如果题目说“DMA传送期间CPU不能访存”那考的就是这种方式。计算CPU效率损失时直接用DMA传送时间除以总时间即可。3.2 周期挪用方式这是实际系统中最常用的方式也是考试中最常考的方式。核心思想是DMAC每次只“偷”一个或几个存取周期传完一个字就把总线还给CPU。如果此时CPU正在访存DMAC就等一个周期如果CPU不需要访存比如正在执行加法指令DMAC就趁虚而入。这种方式下DMAC需要为每个字的传送都申请一次总线控制比停止CPU方式复杂但CPU的访存效率高很多。CPU感觉不到明显的阻塞只是在某些存取周期上会和DMAC产生竞争。周期挪用方式有一个关键参数DMA传送占用存取周期的比例。假设主存存取周期为TDMAC每传送一个字需要占用一个存取周期传送N个字就需要N个存取周期。如果CPU在这段时间内需要访存M次那么实际可用的存取周期就是总周期数减去被DMA挪用的周期数。24年那道45题考的就是这个计算。题目给出CPU执行一段程序需要多少个机器周期其中多少涉及访存然后问DMA挪用多少个存取周期。解题的关键是DMA只在CPU不访存的周期才能挪用如果CPU正在访存DMA需要等待。所以实际挪用的周期数取决于CPU访存的密度。我拿一个具体例子算一下。假设主存存取周期为0.5微秒CPU执行一条指令平均需要2个机器周期其中1个是访存周期。现在有一个DMA请求要传送1000个字。如果采用周期挪用方式DMAC每传一个字需要一个存取周期总共需要1000个存取周期即500微秒。在这500微秒内CPU如果一直在执行程序大约可以执行500/1500条指令每条指令2个机器周期其中1个访存也就是需要500个访存周期。但主存总共只有1000个存取周期DMA占用了1000个CPU就没得用了。实际上DMAC会和CPU竞争最终DMA传送1000个字的时间会拉长因为要等CPU不访存的间隙。这个计算在考试中通常会简化题目会告诉你CPU访存概率或者访存周期占比然后让你算DMA实际占用多少周期。核心公式是DMA实际传送时间 数据量 × 存取周期 / (1 - CPU访存占比)。3.3 交替访存方式这种方式最适合CPU和DMAC速度匹配的场景。它把存取周期分成两个时间片一个给CPU用一个给DMAC用。两者交替访问主存互不干扰。优点是CPU和DMA都不需要等待效率最高。缺点是硬件控制复杂需要精确的时序配合而且要求CPU和DMAC的存取周期匹配。如果CPU的存取周期和DMAC不一致就需要额外的同步逻辑。在实际芯片设计中这种方式常见于CPU和DMA共享同一块双端口RAM的场景。但在408考试中这种方式考得相对少一些因为计算比较简单——直接按时间片分配即可。3.4 三种方式的对比与选型对比维度停止CPU访存周期挪用交替访存总线占用整块独占按字申请固定时间片CPU阻塞程度完全阻塞部分阻塞几乎不阻塞控制复杂度简单中等复杂适用场景高速小数据块通用场景CPU与DMA速度匹配408考试频率中等最高较低选型的核心逻辑是看外设的数据速率和CPU的访存需求。如果外设速率极高且数据块小停止CPU方式可以接受如果外设速率中等且CPU需要持续访存周期挪用是首选如果两者速度匹配且硬件支持交替访存效率最高。4. DMA传送的完整实操流程与关键参数4.1 从CPU初始化到传送结束的完整时序DMA传送不是一瞬间完成的它有一个完整的流程。我以磁盘读取为例把每一步拆开讲。第一步CPU初始化DMAC。CPU执行几条输出指令把主存起始地址写入AR把传送字数写入WC把外设地址写入DAR把传送方向读/写、传送方式周期挪用/停止CPU、是否自动重装等控制信息写入控制寄存器。这一步是CPU主动执行的不涉及总线仲裁。第二步CPU启动外设。CPU向外设接口发启动命令外设开始准备数据。比如磁盘开始寻道、旋转等待扇区。第三步外设发出DMA请求。当外设准备好一个数据单位比如一个扇区的数据已经读到接口的缓冲区它向DMAC发出DMA请求信号DREQ。第四步DMAC向CPU申请总线。DMAC收到DREQ后向CPU发出总线请求信号HOLD。CPU在当前总线周期结束后发出总线响应信号HLDA把总线控制权交给DMAC。第五步DMAC传送数据。DMAC获得总线后把外设接口中的数据读到BR然后写入主存AR指向的地址。或者反过来从主存读出写入外设。每传一个字AR加一或减一WC减一。第六步释放总线。如果是周期挪用方式传完一个字DMAC就释放总线CPU可以继续访存。如果是停止CPU方式DMAC继续持有总线直到WC归零。第七步传送结束发出中断。WC减到零时DMAC向CPU发出中断请求。CPU响应中断执行中断服务程序检查传送是否成功然后进行后续处理比如处理下一块数据或通知应用程序。这个流程在408题目中经常以时序图的形式出现要求你标出各个信号的变化时刻。关键点是DMA请求可以在CPU总线周期的任意时刻发出但总线响应必须等到当前总线周期结束。这就是为什么DMA传送会“挪用”存取周期——它只能在一个完整的存取周期结束后才能接管总线。4.2 关键参数的计算方法DMA传送涉及几个关键参数考试和实际配置中都需要计算。传送字数由WC决定等于数据块大小除以数据单位宽度。比如要传送4KB数据数据宽度为4字节则WC1024。传送时间如果采用停止CPU方式传送时间 字数 × 存取周期。如果采用周期挪用方式传送时间 字数 × 存取周期 / (1 - CPU访存占比)。这个公式的推导逻辑是在每个存取周期内DMA和CPU竞争总线DMA能拿到的概率是(1 - CPU访存占比)。CPU效率损失停止CPU方式下损失 DMA传送时间 / 总时间。周期挪用方式下损失 DMA挪用的周期数 / 总周期数。我拿一个典型题目算一遍。假设主存存取周期为0.5微秒CPU平均每2个存取周期访存一次访存占比50%。现在要传送2000个字。采用周期挪用方式DMA实际传送时间 2000 × 0.5 / (1 - 0.5) 2000微秒。在这2000微秒内CPU可以执行2000/0.5 4000个存取周期其中2000个用于访存2000个被DMA挪用。CPU的效率损失是50%。如果采用停止CPU方式DMA传送时间 2000 × 0.5 1000微秒。在这1000微秒内CPU完全不能访存效率损失100%。但传送时间短了一半。这就是典型的“效率换时间”权衡。4.3 STM32中DMA的实际配置要点虽然408考的是原理但很多同学学完之后会去玩STM32这里我把STM32 DMA配置中的关键点和408知识点对应起来讲。STM32的DMA控制器有多个通道每个通道可以独立配置。关键寄存器包括CPAR外设地址寄存器对应DMAC的DAR存放外设数据寄存器的地址。CMAR存储器地址寄存器对应DMAC的AR存放主存缓冲区地址。CNDTR数据项数寄存器对应DMAC的WC设置要传送的数据个数。CCR通道配置寄存器配置传送方向、数据宽度、优先级、循环模式、中断使能等。配置流程和408讲的完全一致先使能DMA时钟然后配置CPAR、CMAR、CNDTR最后配置CCR并使能通道。传送完成后CNDTR归零如果使能了传输完成中断就会触发中断。有一个实际配置中容易踩的坑数据宽度对齐。如果外设数据宽度是8位存储器数据宽度是16位DMA会怎么处理STM32的DMA支持独立配置外设和存储器的数据宽度但传送时以较小的宽度为准可能会产生数据对齐问题。比如外设8位、存储器16位DMA会把两个8位数据拼成一个16位写入存储器。如果顺序搞反了数据就乱了。这个细节在408中不考但实际调试中经常遇到。另一个坑是循环模式与普通模式的选择。循环模式下CNDTR归零后自动重装DMA持续不断地传送。这适合ADC连续采集、串口持续接收等场景。普通模式下CNDTR归零后DMA停止需要重新配置才能再次传送。选错了模式要么数据只传一次就停了要么DMA停不下来。5. 常见问题与排查技巧实录5.1 408做题中的典型陷阱陷阱一混淆DMA请求和中断请求的优先级。DMA请求的优先级高于中断请求因为DMA请求对应的是数据传送的实时性如果被中断打断可能导致数据丢失。在总线仲裁中DMAC的优先级也高于CPU。题目如果问“DMA请求和中断请求同时发生CPU先响应哪个”答案是DMA请求。陷阱二误以为DMA传送完全不经过CPU。严格来说DMA传送的初始化写寄存器和结束处理中断服务还是需要CPU参与的。DMA只是把数据搬运的过程从CPU手中拿走了但控制流仍然需要CPU。题目如果问“DMA方式下CPU完全不参与”这是错的。陷阱三周期挪用方式下DMA传送时间的计算。很多人直接用字数乘以存取周期忽略了CPU访存的竞争。正确的做法是考虑CPU访存占比DMA实际传送时间会拉长。如果题目给出“CPU访存概率为p”则DMA传送一个字平均需要的时间是存取周期/(1-p)。陷阱四DMA传送与CPU访存的冲突处理。当DMA和CPU同时请求访存时通常DMA优先级更高。但有些题目会设定“CPU正在访存时DMA等待”这时DMA的实际传送时间取决于CPU访存的密度。需要根据题目给出的时序图或访存模式来具体分析。5.2 实际调试中的常见问题速查表问题现象可能原因排查方法解决方案DMA传送不启动通道未使能或DREQ未触发检查CCR的EN位和外设的DMA请求配置使能通道确认外设已启动传送数据错位数据宽度不匹配检查CPAR和CMAR的数据宽度配置统一数据宽度或调整对齐方式传送一半就停了CNDTR设置错误或传输模式选错检查CNDTR值和循环/普通模式修正CNDTR选择正确模式传送完成后没有中断中断未使能或中断标志未清除检查CCR的TCIE位和中断标志寄存器使能传输完成中断清除标志CPU访存变慢DMA占用总线过多检查DMA优先级和传送方式降低DMA优先级或改用周期挪用数据覆盖循环模式下缓冲区未及时处理检查CNDTR重装和缓冲区大小增大缓冲区或降低传送速率5.3 独家避坑经验经验一DMA传送方向别搞反。STM32的CCR寄存器中DIR位决定方向0表示从外设读到存储器1表示从存储器写到外设。我见过有人调串口发送结果DIR设成了0数据从串口DR读到内存当然发不出去。记住外设到内存是“读”内存到外设是“写”。经验二CNDTR的单位是“数据项”不是“字节”。如果你配置数据宽度为16位CNDTR设为100实际传送的是200字节。很多人按字节数设置CNDTR结果传送的数据量翻倍或减半。正确做法是CNDTR 总字节数 / 数据宽度。经验三DMA和CPU同时访问同一块内存会出问题。如果CPU正在读写某个缓冲区DMA同时也在传送数据到这块缓冲区数据可能被覆盖或读到中间状态。解决方案是使用双缓冲DMA传一块CPU处理另一块或者使用内存屏障确保顺序。经验四传输完成中断里别做耗时操作。DMA传输完成中断的服务程序应该尽量短只做标志设置或缓冲区切换。如果在中断里做大量数据处理会阻塞后续DMA请求的响应导致数据丢失。我一般是在中断里只置一个标志主循环里检查标志再处理数据。经验五注意DMA的地址对齐。有些平台要求DMA传输的源地址和目的地址必须对齐到数据宽度。比如16位传输要求地址是2的倍数32位传输要求地址是4的倍数。不对齐可能导致传输错误或硬件异常。配置前先检查缓冲区地址的对齐情况。6. DMA在408考试中的出题规律与备考建议6.1 历年真题中的DMA考点分布翻一遍408历年真题DMA相关的题目主要集中在几个方向DMA与中断方式的对比、DMA三种传送方式的效率计算、DMA控制器的组成部件、DMA传送的时序分析。其中周期挪用方式的效率计算出现频率最高几乎每隔几年就会考一次。24年那道45题考的是DMA传送过程中CPU访存被挪用的周期数计算。题目给出了一段程序的执行时序和DMA请求的时刻要求计算DMA挪用了多少个存取周期。解题的关键是画出时间轴标出CPU访存周期和DMA请求时刻然后看哪些CPU访存周期被DMA“抢走”了。这类题目的通用解法是先确定DMA请求发生的时刻然后看从该时刻开始CPU还有哪些访存周期。DMA会优先占用CPU不访存的周期如果CPU一直在访存DMA就需要等待。实际挪用的周期数等于DMA需要传送的字数但传送时间会拉长。6.2 备考策略与复习重点如果你时间有限DMA这部分优先掌握以下内容第一三种传送方式的区别和效率计算。这是必考内容尤其是周期挪用方式。把公式记牢DMA实际传送时间 字数 × 存取周期 / (1 - CPU访存占比)。第二DMA控制器的组成部件。AR、WC、BR、DAR、控制/状态逻辑、中断机构每个部件的功能要能说出来。考试可能以选择题或简答题形式出现。第三DMA与中断方式的对比。从数据路径、打断粒度、优先级、适用场景四个维度对比。这个知识点经常以选择题形式出现。第四DMA传送的完整流程。从CPU初始化到传送结束中断每一步的信号变化要清楚。时序图题需要能标出关键信号。第五DMA方式下的CPU效率分析。停止CPU方式和周期挪用方式下CPU的效率损失分别是多少。这个和第一点有重叠但更侧重效率分析。6.3 从考试到实战的衔接408考的是原理但原理和实战是相通的。你在STM32里配置DMA时遇到的每个寄存器在408教材里都有对应的部件。CPAR对应DARCMAR对应ARCNDTR对应WCCCR对应控制/状态逻辑。把教材里的原理图和实际芯片的框图对照看理解会深很多。我当年备考时就是一边看唐朔飞的教材一边拿STM32的参考手册对照。教材讲的是通用原理参考手册讲的是具体实现。两者结合既能把题做对又能把代码调通。后来工作中用到Linux DMA、SPI DMA、串口DMA发现底层逻辑完全一样——都是初始化、申请总线、传送、中断这几步。DMA这个知识点考试考的是计算和对比实战考的是配置和调试。但核心思想只有一个把CPU从数据搬运中解放出来让专门的硬件干专门的事。理解了这个思想不管是做题还是调代码都不会跑偏。
返回列表