ARTICLE DETAIL

资讯详情

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

DMA控制器详解:从周期挪用原理到STM32实战

DMA控制器详解:从周期挪用原理到STM32实战 计算机组成原理里关于I/O控制方式的考点说来说去绕不开DMA。很多同学学到这一章前脚刚把程序查询和中断方式理清楚后脚就被DMA控制器的各种寄存器、周期挪用、总线请求给搞晕了。这太正常了因为DMA跟前面两种方式在思路上是完全不同的——程序查询和中断本质上是CPU在“干活”而DMA是CPU把“干活权”暂时让给了一个专门的硬件控制器。这篇文章就围绕408计算机组成原理里I/O设备与主机信息传送控制方式中的DMA方式展开。我会先把DMA为什么会出现讲清楚再把DMA控制器的结构、三种传送方式、完整工作流程拆开揉碎最后用一整个章节讲做题和复习时最容易踩的坑再延伸一点真实硬件里的DMA应用。这篇内容对准备408考研的同学来说可以直接当复习笔记用对正在接触STM32、嵌入式DMA开发的同学也有参考价值。1. 为什么非要有DMA先看前两种方式把CPU折腾成什么样1.1 程序查询方式的痛点CPU成了“人肉轮询器”程序查询方式是最原始的I/O控制方式。它的逻辑非常简单CPU不断读取外设的状态寄存器检查设备是否准备好准备好就传一个数据没准备好就继续查。简单归简单效率低到令人发指。我习惯用一个比喻程序查询方式相当于你坐在工位上每隔几秒钟就抬头看一眼门口看快递员来了没有。在快递员没来的这段时间里你什么都干不了因为你需要持续监控状态。CPU在这种方式下做I/O意味着CPU从外设启动到数据传完的整个过程中几乎全程都在“陪着”外设转。以最典型的主机向打印机输出一个字符为例CPU要反复发出读状态命令、判断状态位、写数据、改状态这中间每一个环节都需要CPU执行若干条指令。每个字符的传送背后是成百上千条指令。更难受的是CPU的执行速度和外设的速度差距极大。CPU主频几个GHz而慢速外设比如键盘每秒钟也就产生几十个字符。如果让CPU用查询方式去伺候键盘CPU的绝大部分算力都消耗在“查询”本身真正用于计算的时间几乎没有。所以在讨论I/O方式的时候第一条要记住的就是程序查询方式虽然控制简单、硬件代价低但CPU的利用率被拉到了极低的水平而且CPU和外设只能串行工作。1.2 中断方式的改进与短板每个字都喊一次救兵中断方式改进了程序查询“死等”的问题。CPU不再主动轮询而是先告诉外设“你准备好就喊我”然后CPU转头去执行主程序。外设准备好一个数据后通过中断请求线向CPU发信号CPU响应中断暂停当前程序跳转到中断服务程序完成一次数据传送再返回断点继续执行。这个方案的进步在于CPU不再为空闲等待买单外设没准备好的时间里CPU可以干别的事情。但中断方式仍然有个绕不开的毛病——每一次数据传送都要经历一次完整的中断响应过程。中断响应要做的事情非常多关中断、保存断点、保存现场、识别中断源、跳转中断服务程序、恢复现场、开中断、返回断点。这一整套流程少说也要几十条指令。问题就出在这里外设每传一个数据CPU就要被中断一次。如果外设传一个128字节的数据块CPU就要被中断128次。每次中断都有保存和恢复现场的固定开销而且这些开销是纯“浪费”的——它们不产生任何计算结果。对于低速设备中断次数少开销还能接受但对于磁盘、网卡这类一次性要传大量数据的设备中断方式就显得非常吃力大量CPU时间被耗在中断现场保护和恢复上。再加上频繁的中断还会打乱CPU的流水线执行实际的性能损失比账面上的几十条指令更大。1.3 DMA的破局思路让硬件去批量搬运程序查询方式是“CPU全程陪跑”中断方式是“每传一个数据CPU被叫醒一次”。这两种方式的本质都是数据传送必须由CPU执行指令来完成。问题是为什么数据传送一定要CPU亲自做能不能设计一个专门的硬件控制器让CPU只在最开始告诉它“从哪来、到哪去、传多少”然后就撒手不管由这个硬件控制器自己把整块数据传完这——就是DMADirect Memory Access直接存储器存取的核心思想。DMA方式下外设与主存之间的数据传送由DMA控制器DMAC直接负责数据不经过CPU内部寄存器而是直接在内存和外设之间建立数据通路。CPU要做的只有两件事传送前做预处理设置首地址、传送字数、启动命令传送结束后做后处理响应DMA的中断请求检查传送是否正确。这样做的收益非常明显传送一个数据块CPU只在开始和结束的时候介入中间的整段数据搬运完全由DMA控制器完成。用中断方式传128字节可能要中断128次用DMA方式整个数据块只需要CPU参与一次预处理和一次后处理。这就是DMA方式在需要高速大批量数据传送的场景磁盘、网卡、显卡、串口高速通信中成为标配的根本原因。2. DMA的三种传送方式搞懂“周期挪用”就赢了一半2.1 三种方式的定义和特点在408教材里DMA的数据传送方式通常有三种CPU停止法成组传送、周期挪用周期窃取、DMA与CPU交替访存。三种方式的区别核心在于“DMA控制器占用总线的时机和长度”不同。CPU停止法最简单粗暴DMA控制器获得总线控制权后CPU就完全让出总线的使用权DMA独占总线连续传送完整个数据块然后才把总线还给CPU。这种方式的好处是控制逻辑简单传送速度快缺点是CPU在数据块传送期间基本被“架空”虽然理论上有DMA控制器的系统里CPU还能干点不访存的内部操作但对于没有Cache的早期系统CPU几乎等于停机等待。所以这种方式更适合高速外设且数据块很大的场景——反正CPU也插不上手干脆让DMA一次干完。周期挪用法也叫周期窃取是教学和考试中的重点。它的思路是DMA控制器不独占总线而是每传送一个数据字就向CPU“借用”一个总线周期。用完立即归还然后等下一个数据准备好再次申请总线周期。这种方式把大块数据传送切成了一个个小的总线周期对CPU的影响明显减小CPU只是偶尔被“插空”暂停一个总线周期大部分时间照常执行程序。DMA与CPU交替访存也叫透明方式。这种方式要求主存可以被两个端口同时访问CPU和DMA控制器各自使用独立的地址线和数据线按时间片轮流访存。每个存储周期内一半时间给CPU用一半时间给DMA用。这种方式CPU几乎感觉不到DMA的存在但硬件代价很大需要双端口存储器所以应用场景相对受限考试中以了解为主。2.2 周期挪用到底是“怎么偷”总线的周期挪用的过程值得细抠因为这是考试喜欢出选择题和简答题的地方。我把它拆成几个时间点来看。外设准备好一个数据后向DMA控制器发出DMA请求DREQ。DMA控制器收到这个请求后向CPU发出总线请求HRQHold Request表示“我想用一下总线”。CPU在执行完当前正在进行的总线周期后检测到HRQ信号会让出自己的总线控制权回一个总线应答信号HLDAHold Acknowledge。DMA控制器收到HLDA后获得总线使用权用一个总线周期把外设准备好的这个数据写入主存或从主存读出到外设然后立刻释放总线把控制权还给CPU。这里有几个容易搞错的地方。第一次学的时候很多人以为周期挪用是“DMA把整个数据块一次搬完搬完才释放总线”其实不对。周期挪用是每次只挪用一两个总线周期用来传一个数据字传完就释放。整个数据块是由一次次短促的挪用拼凑完成的。也就是说外设准备好一个字DMA来挪用一个周期准备下个字再来挪用一次。所以周期挪用特别适合外设速度不是特别快、数据是一个一个准备好的情况。还有一个必须注意的点CPU让出总线的时机是当前总线周期结束之后而不是当前指令执行完之后。450毫微秒的一个总线周期之后CPU就会把总线交给DMA。但CPU内部的指令执行可能还在继续如果指令流水线需要访问主存就会因为总线被占用而插入等待状态。所以周期挪用虽然影响小但确实会延长CPU执行程序的时间只是延长的量很小罢了。2.3 三种方式的对比与适用场景把三种方式放在一起看它们之间的取舍关系非常清楚。CPU停止法适合数据块大、传送速率要求极高的场景代价是CPU长时间离线周期挪用适合大多数中高速外设对CPU影响小、硬件实现适中是实际中最常用的方案交替访存对CPU影响最小但需要有双端口存储器成本最高。考试里如果问“某外设每秒钟需要传送多少数据采用周期挪用对CPU的影响有多严重”本质上是在算“挪用比例”。比如外设每80个总线周期产生一个数据那么DMA大约每80个周期挪用1个周期CPU的访存效率大约损失1/80。如果外设速度很快每两个周期就产生一个数据DMA挪用比例就是50%CPU的存取速度几乎被吞掉一半这时就得考虑换用其他方案或者提升总线带宽。3. DMA控制器内部拆解每个寄存器都是干什么的3.1 核心寄存器组DMA控制器不是简单的一个“数据搬运开关”它内部包含一组寄存器各自承担明确的任务。我把它们列出来你在复习的时候最好能做到闭着眼默写。主存地址寄存器ARAddress Register用来存放当前要访问的主存单元的地址。每传送一个数据AR会自动加1或减1指向下一个主存单元。这个自动增减的过程完全由硬件完成不需要CPU干预这是DMA效率高的直接原因之一。数据缓冲寄存器BRData Register用来暂存从外设读入或准备写往外设的数据。外设和主存之间往往速度不匹配数据缓冲寄存器起到临时中转的作用。注意DMA的数据缓冲寄存器每次暂存的通常是一个字DMA控制器核心的数据通路宽度也就是一个字。字计数器WCWord Counter用来记录需要传送的数据总字数。每传送一个字WC减1当WC减到0时说明数据块传送完毕DMA控制器会向CPU发出中断请求报告传送结束。设备地址寄存器DARDevice Address Register用来存放外设的设备号或外设的地址信息用于选择对应的外设。在DMA启动时由CPU写入。状态和控制寄存器用来存放控制信息比如传送方向读/写、传送方式单字/成组、中断允许位等。CPU通过向这些控制位写入数据来配置DMA的工作模式。除了寄存器DMA控制器内部还有DMA控制逻辑和中断机构。控制逻辑负责产生主存地址、修改字计数、发出读写命令、判断传送是否完成等操作中断机构负责在数据块传送结束时向CPU发出中断请求让CPU进行后处理。3.2 工作流程从预处理到后处理DMA的完整工作过程可以分成三个阶段预处理、数据传送、后处理。三个阶段里只有预处理和后处理需要CPU参与数据传送阶段CPU完全不干预。预处理阶段CPU执行几条指令向DMA控制器写入必要的信息。具体包括向设备地址寄存器写入外设地址向主存地址寄存器写入主存起始地址向字计数器写入传送的数据块长度然后启动外设。这几步做完CPU就回去继续执行自己的程序了。数据传送阶段完全是DMA控制器和外设之间的“双人舞”。外设准备好数据后发出DMA请求DMA控制器协调总线使用权把数据从外设写入主存或者从主存读出送到外设同时修改地址寄存器和字计数器。这个过程循环往复直到字计数器归零。后处理阶段DMA控制器向CPU发出中断请求CPU响应后进入中断服务程序做一些收尾检查工作比如确认数据是否传送正确、判断是正常结束还是出错结束然后撤销外设的DMA请求信号让外设停止工作。这里有一个非常经典的考点DMA方式下数据传送阶段CPU不参与但预处理和后处理阶段CPU是要参与的。很多人刚学的时候误以为“DMA完全不需要CPU”然后把预处理和后处理也当成DMA控制器的活儿这就大错特错了。DMA节省的是“逐字传送过程中的CPU开销”而不是完全把CPU排除在I/O流程之外。3.3 一个容易想错的点DMA和CPU谁在控制总线DMA控制器获得总线控制权之后它在物理上替代CPU成为了总线主设备。这个过程中CPU并没有“死机”它只是暂时失去了对地址线、数据线和控制线的使用权。对于现代CPU来说失去了总线使用权意味着无法访问主存也无法访问I/O端口但它内部的寄存器操作、Cache命中访问这些不需要总线的操作还能继续执行。所以准确说法是DMA占用总线期间CPU可能仍然在执行指令但如果这些指令需要访存就会被“挂起”。有些教材把这描述为“CPU停止工作”那是简化说法。在早期的单总线结构中因为没有CacheCPU一旦失去总线就真的什么都干不了了所以那时的成组传送对CPU的影响接近100%。但在带Cache的系统中CPU大部分时间访问Cache对外部总线的依赖度降低DMA对CPU执行的拖累会减轻不少。这个区别在衡量“DMA对CPU性能影响”时非常关键。4. DMA、程序查询、中断一张表看清三者的区别4.1 数据通路与CPU介入程度对比三种I/O方式的本质区别可以从两个维度看一是数据从哪里到哪里二是CPU在每个环节里扮演什么角色。程序查询方式下数据从外设到CPU再从CPU到主存。也就是说CPU内部寄存器是数据传送的必经之路主机和外设之间没有直接的数据通路。中断方式也是一样每个数据都要经过CPU的寄存器中转。而DMA方式下主存与外设之间由DMA控制器直接建立数据通路数据不经过CPU内部寄存器。正是因为数据通路不同CPU的介入程度也完全不同。程序查询需要CPU逐字检查状态、逐字传送中断方式虽然不需要CPU死等但每一次传送都要CPU响应中断并执行传送程序DMA只需要CPU预处理和后处理。这个介入程度的差异直接决定了三种方式在高速大块数据传送场景下的性能表现。我觉得可以这样理解程序查询是CPU一把屎一把尿把每个字节伺候到位中断是CPU每个字节被叫醒一次去接货DMA是CPU一次性把收货单填好让一个专门的搬运工DMA控制器把一整批货搬完最后签个字确认收货。4.2 响应时机、开销、速度的全方位对比三种方式在多个维度上都有鲜明区别我整理了一张对比表复习的时候可以直接拿来用。对比项程序查询中断方式DMA方式数据传送单位字字节字字节数据块数据通路CPU寄存器中转CPU寄存器中转DMA控制器直达主存CPU介入程度全程参与每次传送都要响应中断仅预处理和后处理响应时机CPU主动查询指令执行周期结束后响应中断总线周期结束后让出总线硬件代价最低较低较高适用场景低速简单外设中低速外设、实时性要求高的场景高速大块数据传送场景这张表里值得细看的是“响应时机”。程序查询不存在“响应”问题因为CPU什么都可以查中断请求是在一条指令执行完后被采样因为要保证当前指令能够完整执行完否则指令的原子性就被破坏了而DMA总线的请求是在当前总线周期结束后被响应因为总线周期比指令周期更短。很多填空题和选择题就喜欢考“DMA请求在什么时刻被响应”——答案是总线周期结束时不是指令周期结束时。在开销方面中断方式的固定开销是“现场保存现场恢复”DMA的固定开销是“预处理指令中断后处理”。当传送的数据量很小的时候DMA的预处理开销可能比分次中断的累计开销还要大所以DMA并不是“什么场合都好”它适合数据块较大的场景。这个“块大小阈值”的概念在工程上非常实用。4.3 408考研高频考点这些细节最容易被出题人盯上结合历年真题的出题风格我总结几个高频考点你在复习的时候可以重点标注。第一个是“谁在什么阶段做什么事”的判断题。比如预处理阶段主存起始地址、传送字数由CPU写入传送阶段主存地址的修改、字计数的减一是由DMA控制器硬件完成的后处理阶段对传送结果进行检查的是CPU。这种题干喜欢打乱主体让你判断对错本质考的就是三个阶段的分工。第二个是“周期挪用与CPU执行的关系”。比如给出一个机器周期和存取周期的数值问DMA每传送一个数据字需要占用几个总线周期或者一个数据块传送完CPU被拖慢了多长时间。这类是计算题的基础。第三个是“DMA与中断的区别”。DMA方式结束后要向CPU发中断请求这是很多人的迷惑点——既然DMA已经不需要CPU了为什么还要发中断答案是数据块传完了CPU需要知道结果以便进行错误检查、启动下一次传送等善后工作。这个中断是“整块数据传完才发一次”不是“每个字发一次”和中断方式的中断频率完全不同。第四个是“I/O方式的选择”。给一个应用场景问你选哪种方式最合适——键盘适合用中断或查询硬盘和网卡适合用DMA。这类题目只要抓住“数据规模”和“速度要求”两个核心指标基本不会错。5. 做题与复习时最容易踩的坑5.1 “一个数据块传送一次总线请求”到底对不对很多辅导书和习题里有一个经典说法DMA方式是“以数据块为单位传送”。这个说法本身没问题但容易被误解成“DMA一次总线请求就传送整个数据块”。真相要看具体是哪种传送方式。在周期挪用方式下DMA每传送一个字就要发起一次总线请求整个数据块由成百上千次短促的请求拼接完成。只有在成组传送CPU停止法方式下才是一次总线请求、独占总线、连续传送整个数据块。所以如果题目没有特别说明是成组传送默认说“DMA每传送一个数据字都需要占用一次总线”这在周期挪用场景下是成立的。这个考点在选择题里极具迷惑性。出题人经常把“数据块传送”“总线请求次数”“周期挪用占比”混在一起让你判断哪些说法正确。我的建议是做题时先判断题目默认的DMA方式是哪一种如果题目给了“外设准备好一个数据就发一次请求”的条件那就是周期挪用如果题目说“DMA启动后连续传送直到结束”那就是成组传送。5.2 周期挪用对CPU的影响怎么算周期挪用的影响算起来有个关键前提取DMA控制器挪用的是主存总线周期而CPU执行指令需要多个总线周期。假设一个总线周期是200纳秒CPU执行一条指令平均需要5个总线周期即1微秒那么DMA每挪用1个总线周期CPU执行这条指令的时间就会从1微秒延长到1.2微秒。更完整的计算方式是这样的先算出外设产生数据的速率比如外设每秒要传送10000个字每个字需要挪用1个总线周期。如果总线周期是200纳秒那么DMA每秒挪用10000个总线周期也就是挪用2毫秒的总线时间。再看CPU的总执行时间如果CPU每秒执行5000微秒的指令被DMA挪用2毫秒CPU的有效执行时间减少了约0.04%。这里我给的数字只是一个示例核心方法是DMA每秒占用的总线周期数除以系统每秒可提供的总线周期总数这个比值就是总线被占用的比例也约等于CPU访存效率下降的比例。但这里有个坑不是每次DMA请求都能立刻被响应。如果外设的数据是突发到达的多个DMA请求挤在一起可能发生等待。所以实际影响还要考虑请求的分布。考试题目通常会理想化为均匀分布做题时按比例计算即可。5.3 几个高频易混概念中断、DMA、通道、IOP复习到I/O这一章最让人头疼的是DMA和通道、IOP输入输出处理器之间的关系。很多人问DMA已经有了为什么还要通道我的理解是DMA控制器本质上只能完成数据传送这一件事。它不知道数据块的意义不会对数据进行加工也不能管理多个外设的复杂调度。当系统里有大量高速外设且需要不同设备进行优先级调度、数据格式转换、校验等复杂操作时单靠多个DMA控制器会导致硬件逻辑极其复杂。于是出现了通道——一种比DMA更高级的I/O控制部件。通道可以执行通道程序能控制多台外设能在传送数据的同时做简单处理。IOP则更进一步带有更强的运算能力本质上是I/O子系统里的专用处理机。考试里如果拿DMA和通道对比记住几个关键差异DMA通过硬件逻辑控制传送通道通过执行通道程序控制传送DMA适合单一或少数外设的大块数据传送通道适合多台外设的复杂I/O管理DMA的预处理功能简单通道的功能更完备。做题时不会混淆因为DMA的考题集中在寄存器、周期挪用和流程通道的考题集中在通道程序、分类和与DMA的比较。还有一种容易混淆的是“DMA与中断方式的结合”。DMA传送结束后向CPU发出中断请求用的是中断机制但整个数据传送本身不依赖中断。所以可以说“DMA用到了中断机制但不是中断方式的数据传送模式”。这个概念理清楚后面做题就不容易乱。6. 从课本到工程DMA在真实设备里是怎么用的6.1 磁盘、网卡、显卡这些设备为什么非用DMA不可课本上讲的DMA原理到了真实系统里几乎是所有高速外设的标配。最典型的例子是磁盘。机械硬盘内部扇区读出来之后如果靠CPU逐字去搬以磁盘每秒几百兆字节的传输速度CPU根本扛不住。磁盘控制器把读出的数据块直接通过DMA写入内存指定缓冲区只在一个数据块读完后向CPU发一个中断CPU从缓冲区取数据就行。这里的中断频率大概是磁盘转速决定的比如每秒几百次跟按字节传输的密集型中断完全不是一个量级。网卡的收包过程也一样。网卡收到一帧数据后通过DMA把数据直接写入内存中的接收环形缓冲区写完后通知驱动去处理。如果每收一个字节就中断一次CPU那千兆网卡一秒钟能产生上亿次中断没有任何操作系统能承受这种负担。DMA的意义就在于把“频繁、大量、简单重复的数据搬运”从CPU身上彻底剥离。还有图形设备。显卡的显存与主存之间的数据交换无论是纹理上传还是帧缓冲更新都走DMA通道。用户在屏幕上拖动窗口时那部分图像的拷贝就是由DMA完成的。可以说没有DMA现代PC的多媒体体验会直接崩溃。6.2 STM32里配置一次DMA核心参数只有这几个很多学计算机组成原理的同学同时也在接触嵌入式开发说到DMASTM32毫无疑问是入门首选。其实你在STM32上配置DMA时用的概念跟课本完全对得上。打开STM32的DMA配置最重要几个字段是外设地址、存储器地址、数据传输方向、传输数据量、外设地址增量、存储器地址增量和循环模式。外设地址对应课本里的设备地址寄存器存储器地址对应主存地址寄存器传输数据量对应字计数器。使能地址增量模式后DMA每传一个数据地址自动加1对应课本说的AR自动修改传输数据量写到0就是字计数器归零传送结束。我举个串口接收的例子用UART接收一帧不定长数据传统做法是每个字节触发一次接收中断CPU进中断把数据搬进数组。用DMA的做法是配置好UART的RX DMA通道把目标地址设为数组首地址数据量设为最大可能长度开启UART的空闲中断然后CPU完全不管接收过程。当一帧数据到达后数据自动被DMA搬进数组空闲中断触发后CPU通过计算DMA剩余计数来推算实际收到的字节数。这样配置下来小数据块用DMA可能看不出什么优势但大数据量比如几十字节以上的不定长串口帧、ADC连续采样数据时CPU占用率的差别非常明显。课本里说的“数据块大才值得用DMA”在真实MCU开发里是完全成立的。6.3 实际工程中用DMA的三个经典坑工程上踩过的坑比书本上的考点更具体。第一个坑是DMA中断标志的清除顺序。很多MCU要求在读取剩余数据计数器之前或之后按特定顺序清除中断标志顺序颠倒可能导致漏掉最后一笔数据或者误触发一次中断。我调试UART DMA接收时曾经因为标志清除顺序不对每收完一帧就多进一次空闲中断排查了很久才发现问题。第二个坑是Cache一致性。到了带Cache的高性能CPU上CPU通过DMA往内存写数据但CPU的Cache里还留着旧数据或者CPU改了内存数据但还没写回DMA去读到的却是旧数据。这就是所谓的Cache与DMA数据不一致问题。Linux内核里有专门的DMA API比如dma_alloc_coherent、dma_map_single来处理缓冲区的Cache一致性裸机或RTOS开发里也要留意必要时做Cache无效化或flush操作。第三个坑是外设速度与DMA频率的匹配。DMA虽然能把CPU解放出来但如果外设数据到达速率超过DMA控制器的处理能力DMA会产生溢出错误。比如ADC用DMA连续采样时如果ADC的触发频率太高DMA每采样一个数据都抢不到总线就会丢数据。解决办法是提高DMA优先级或者降低采样率或者用双缓冲交替传送。课本里的周期挪用概念在这种场景下可以从“CPU被拖慢”的角度反向理解——就算CPU让得再快总线带宽始终是天花板。DMA这块内容我在考研那会儿也反复糊涂过后来是通过两件事彻底想通的。第一件事是动手画了一张流程图把预处理、传送、后处理三个阶段的分工用不同颜色标出来每天睡前看一遍连续看了一周就再也忘不掉了。第二件事是在STM32上真的跑了一次串口DMA接收亲眼看到数据在CPU完全不管的情况下自动进了内存之前所有抽象的概念一下就落地了。如果你现在正被DMA的各种细节绕得头疼我建议你也试试这两个方法先画图再动手。408的考点虽然偏理论但背后对应的全是真实硬件的工作方式。顺着“外设准备好数据—DMA请求总线—CPU让出总线—数据直接进内存—传送完成发中断”这条主线去理解比死记硬背寄存器名字管用得多。等你把DMA真正吃透了再回头看程序查询和中断方式你会对计算机I/O子系统形成一套完整的、体系化的认识这比多刷几道题有价值得多。
返回列表