完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
网上文章一大堆都有介绍DMA的作用,是直接内存获取控制器,但由于用途的局限或者用在了复杂的外设上面,导致没有很好的把DMA的作用说的很系统,本人也是根据网上的资料,进行一些DMA的总结,个人觉得比较系统,也权当是笔记,哈哈。如有错误,请各位大神指正。
DMA的作用是什么? 在没有CPU的参与下,把数据从一个地方搬运到另外一个地方。从这句话,我们可以总结出他的作用: (1)搬运数据。 (2)“一个地方”指的是外设或者内存,外设当然包括片内外设和片外外设,比如ADC、UART片内外设,外挂的flash属于片外外设(最终控制的仍然是内部flash控制器);内存当然包括片内内存和片外内存(仍然是内部的内存控制器),其实,不论外设还是内存,最终都是控制处理器内部的地址。 (3)搬运数据的过程中不需要CPU参与,就是不需要有CPU运行汇编指令,也就是说DMA有自己“CPU”,自己干自己需要干的活。 总结:DMA就是自己把一个地址的数据搬到另外一个地址。 为什么能够DMA?他在处理器中的内部原理图是什么? 从DMA的作用中知道,DMA是把一个地址的数据搬运到另外一个地址,所以它需要控制地址,这些地址在处理器内部是AHB和APB总线矩阵管理的,所以DMA必须要挂到AHB和APB上面,下图是ATMEL ARM9的DMA的框图: 下图是STM32F4XX的DMA内部的框图: 注意,AHB是可以通往操作APB总线的,所以挂到AHB总线上就可以操作外设的。 通过上述的两个图,总结一下: (1)DMA需要把数据从“一个地址”搬运到“另外一个地址”,所以它有“两个出入口”。 (2)挂到AHB总线的“出入口”可以操作APB上的外设,所以ARM9的DMA控制器,可以实现外设到内存、内存到外设、内存到内存搬运3种功能;然而,STM32F4XX的DMA控制器,的DMA2可以实现3种功能,但是DAM1的一个端口只挂到APB总线上,所以他不能实现内存到内存的功能。 (3)一个DMA控制器的构造: (i)数据出入口。 (ii)DMA被编程配置的端口,让CPU可以配置DMA的寄存器。 (iii)硬件握手的接口,需要接收外设的DMA请求和相应请求。 (iv)中断发出接口,当DMA到达某种条件后,需要发出中断通知CPU,比如传输完成、传输出错。 DMA的功能细节描述 首先数据传输三要素:源、目的、大小。在理想情况下,一个寄存器放源地址,一个寄存器存放目的地址,一个寄存器存放数据大小,最后在DMA通道寄存器使能,让DMA愉快的搬运数据即可。理想是美好的,但现实是多变的,其实,在平时使用中,还要满足各种情况,还要考虑很多细节。 (1)源地址的细节。 首先,必须有个寄存器存放源地址,一个地址只能存放一个字节的数据,那么考虑问题: (i)如果源的结构是由2个或者4个字节构成的,怎么办?比如说32位的寄存器其实就是4个字节的构造。 答:此时需要一个寄存器来设置,源地址的构造是字节、半字还是字。 (ii)如果需要传输很多连续单位(字节、半字、字),怎么办? 答:此时需要一个寄存器来设置,源地址传输一个单位后,再传输下一个单位的地址是连续递增或者递减。 (iii)如果传输多个连续单位(字节、半字、字),怎么办? 答:此时需要有多个寄存器设置多个源地址的起始地址。当然别不是所有的DMAC都支持任意多个连续单位,STM32有双buffer功能,就是说可以设置2个起始地址,这两个地址是硬件自动切换的;ARM9通过LLI技术,就是把每个起始地址都提前存放到内存中,形成一个链表,当第一个传输完成后,根据链表查到下一个起始地址的地址,直到最后一个,这种技术可以支持非常多的起始地址,当然链表中的每个节点不只是一个寄存器的内容,下图就是LLI的构造。 (iv)由于DMAC都是挂在AHB总线上,如果需要使用AHB总线,必须要AHB总线仲裁给与权限, 每个获取一次权限发送一个单位的数据,所以说这个单位最多就是一个字,从宏观上看,其实速度已经非常的快了,如果还想更快更多怎么办? 答:此时就产生了“突发”传输的技术,突发传输的核心是以“量和速度”为核心的传输,啥意思、啥东西,这么复杂?通俗的说的说,就是每当DMAC获得AHB使用权的时候,传输多个单位,在STM32中,是通过FIFO来实现的,因为FIFO最多存16字节的数据(4深度32位),DMAC先把数据存入FIFO,存多少,是根据用户的配置,最少要4个节拍,也就是4个单位,等FIFO的数据阈值达到了用户的设定,STM32是有MBURST域决定的,ARM9如下图,由下面的域决定的: 此时DMAC如果获取到了总线的使用权的时候,他会抓住机会不释放总线,直接把用户需求的数据,一次性(分多次)全部传输,下图是“野火”根据英文手册,总结的中文表格(大家都喜欢中文,所以在此引用): 这个图的意思是必须达到这么多节拍才进行突发传输,FIFO阈值,是FIFO要达到总的(16字节)比例,例如用户配置MSIZE=半字,MBURST=4,FIFO级别=1/2,意思就是一次突发由4个节拍(单位)构成,此时达到FIFO的1/2(也就是8个字节),此时MSIZE=半字,所以4半字=8个字节,需要1次突发就可以完成;如果此时FIFO级别=满,此时FIFO里面有16个字节,此时MSIZE=半字,所以(4半字)*2=16字节,因此,需要连续2次突发完成。 在ARM9中,是否使用突发传输不需要额外的配置,只是根据请求传输的类型(single或者chunk)DMAC自己决定是否使用突发传输。 关于请求开始传输数据 (1)不论是DMA还是外设流控,不论是传输方向是内存到外设还是外设到内存,每次传输都是外设发起请求,也就是握手信号由外设产生,但是握手的方式有两种:软件握手和硬件握手。如果是内存到内存模式,就不需要外设参与,也就不需要外设进行请求。 (i)软件握手。 当外设准备好之后,会通过中断的方式通知CPU自己“已准备就绪”,此时CPU写相应的DMAC寄存器开始DMA传输。 (ii)硬件握手。 当外设准备好之后,直接通知DMAC自己“已准备就绪”,此时DMAC直接开始传输。 STM32所有外设请求硬件握手,而ARM9则可以选择硬件还是软件握手,如果设置成硬件握手还需要设置SRC_PER 或者 DST_PER 的域,把域设置成对应的硬件ID号。 关于流控 (1)DMA流控的时候,需要传输数据的多少是在传输之前已知的;外设流控的时候,在传输数据之前,需要传输数据的多少是未知的,此时,如果数据传输完成,需要外设发出信号,通知DMA“数据已经发送完成”,STM32中只有SDIO才有这种功能,其他外设不存在这种功能,所以其他外设都要设置成DMA流控,传输次数寄存器DMA_SxNDTR会被硬件自动设置成0xffff,当传输0xffff次之后,如果硬件不通知DMA停止传输,此时仍然会强制让DMA产生完成中断,同时通道也会被强制关闭。在ARM9中,我们发现并不能使用外设流程,如下图: (2)内存到内存的传输,流控只能是DMAC。 关于FIFO (1)在单次传输的时候可以开启FIFO使用功能,在突发传输的时候,必须使用FIFO功能,因为突发传输,就是以“数据量和传输速度”为目的的。 关于一次传输 (1)什么是一次传输? 一次传输有三要素: (a)原地址以及位宽。 (b)目的地址以及位宽。 (c)传输的次数,STM32由DMA_SxNDTR寄存器决定。ARM9是由DMAC_CTRLAx寄存器的BTSIZE域决定的。 关于开始和结束传输 (1)DMA怎么知道要开始传输了? 当源或者目的(非内存外设)准备好之后,就发出请求,此时DMAC就知道可以进行数据传输了。 当源和目的都是内存外设的时候,就由DMAC控制器,直接进行数据传输,并不需要请求信号。 (a)STM32中,请求信号直接直接与DMAC连接,只有相应的通道使能后,外设准备好之后,就立刻发出请求,并不需要软件参与。 (b)在ARM9中,请求是通过设置寄存器发出的,如下图单次传输请求是在DMAC_SREQ寄出器域中: 下图是在DMAC_CREQ寄存器的chunk请求: ARM9为什么会有两种不同的请求呢?因为ARM9重DMAC并不能通过配置相关的寄存器进行burst突发传输,而是直接根据请求类型来决定是否进行burst突发传输。 (2)CPU怎么知道一次传输完成了? (a)在stm32中,每次传输都会有几种不同的中断产生,当然也可以轮训,下图是可以进行产生的中断种类: 大致有三类:传输一半、传输完成、传输出错。 (b)在ARM9中,也能产生中断,如下图: 大致也是有三类:一个buffer传输完成、buffer链传输完成、传输错误。 通过(a)(b)可知,可以通过相应的标志位或者中断,进行判定传输完成。 (3)循环传输怎么判断传输完成? 在每次的“一次传输”完成都会产生中断标志进的,所以,CPU就能够判断传输完成的。 关于传输模式 (1)直接模式。不使用FIFO,如果有请求直接进行一次传输。 (2)burst突发模式。使用FIFO,根据burst的配置进行突发传输。内存到内存必须使用突发传输。、 直接传输和burst传输的区别就是是否使用FIFO,传输模式软件编程需要注意哪些事项? (1)STM32来说是需要配置是否使用直接模式,默认是直接模式,所以不进行突发传输。 (2)ARM9并不需要配置是否是直接模式,只是根据请求类型来决定使用哪种方式进行传输。 STM32和ARM9的DMA的差异在哪里? (1)握手方面,STM32外设的握手线直接与DMAC连通,并不需要软件配置;ARM9需要进行软件或者硬件握手配置。 (2)传输模式方面,STM32需要配置是否使用FIFO的突发传输;ARM9直接根据请求类型,自己决定是否进行突发传输。 (3)功能方面,STM32可以进行单次传输和双buffer传输;ARM9由于LLI技术,所以可以进行单buffer和多buffer传输。 (4)源和目的地址方面,STM32只能是递增、递减或者固定三种方式;AM9则可以递增、递减、固定或者从LLI中获取。 总结 DMAC就是进行数据搬运的,搬运中由于需求不同,可以进一步细节的优化,burst突发传输、多buffer技术,最后再奉上一个问答题目: DMA请求总线后,CPU把总线控制权交给了DMA,那么CPU不是就没法从内存读取指令和数据了吗?那么,CPU不就处于干瞪眼的状态吗?这样的话,也没法提高CPU的效率啊,还不然直接让CPU去干DMA的活呢? 答:资源是有限的,肯定有争抢和效率的问题(不仅仅是memory,在memory之前还存在对总线的争抢)。但也不用过于悲观,因为(我们从CPU的视角往下说): (1)CPU不是一直在取指和取数。指令执行的过程包取指、译码和执行,译码肯定不需要访问memory,执行访问memory的概率也不会超过50%。 (2)复杂SoC通常有很多级的指令cache和数据cache,在顺序执行的情况下,又可以大大减少CPU访问memory的可能性,降低和DMA冲突、争抢的概率。 (3)复杂SoC的总线通常具有仲裁能力,可以配置CPU、DMA等访问总线的优先级,这很大程度上会影响CPU和DMA对memory的访问,如果不想CPU被影响,可以调高它的优先级,反正DMA传输可以慢慢来(见缝插针,这也是DMA设计的初衷)。 (4)关于CPU和DMA对memory资源的争抢,也可以通过DMA burst size进行调整。 (5)很多时候,系统中的memory(例如DDR),是有并发访问的能力的,可以想象成有多个可并行工作的memory,因此竞争的概率又可以降低了。 (6)最后再强调:DMA的性能和CPU的性能是不可调和的,需要根据实际的应用场景小心的平衡。 |
|
|
|
只有小组成员才能发言,加入小组>>
2514 浏览 0 评论
1092浏览 2评论
703浏览 1评论
456浏览 0评论
200浏览 0评论
341浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 00:13 , Processed in 1.319153 second(s), Total 81, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号