前情提要:装好了虚拟机ubantu,就像准备好了白龙马和通关文牒,可以准备踏上取芯路程了。可这怎么去西天大tapeout寺,路线上的选择还得细细考究。


站在长安城外,对着手上的地图可是犯了难,想要将真经从外设带到内存(SRAM),必须先得带着真经(数据)去西皮尤(CPU)备个案,才能带到内存(SRAM)。可是若是去了西皮尤(CPU),这耗费的路程和时间又不知道要多少万万时钟。

这时候白龙马说到,反正都要走大路(AHB),这不如试试看抄近路走绕城高速(DMA),这一路若是成了,可以减去不少时间。


正常来说数据从外设到SRAM,必须先让CPU搬到自己的内存,再搬到SRAM去。这样不仅占用CPU资源,更是降低速度。为了解放CPU让它不再为搬数据烦恼,DMA应运而生。DMA外设可以“接管”总线,实现内存和外设之间的直接互相传输,相当于“绕城高速”,可以有效提升效率。表面上DMA是外设,其实他依旧要占用总线,还是可以归为core里的。

DMA结构图

DMA核心就是Stream(通道)、Arbiter(仲裁)、FIFO(内存缓冲)。DMA一般有多个通道,而左边的REQ_STREAMX其实可以理解为传输信号,告诉仲裁右边的第X个通道要传数据了,麻烦把路给我们让一让。那如果不同的通道同时告诉仲裁我们都要传,那怎么办?DMA可以在初始设置的时候,用软件给每个通道配备优先级(低、中、高、很高),这样高优先级的通道可以优先传输数据。那如果两个通道优先级一样,仲裁怎么判断呢?那么DMA就会根据硬件设置(0>1>…>8)来决定传输的优先级。

总结来说就是多通道传输不同优先级软件编写,同优先级硬件编写

与其他外设相同,如果要使用DMA,需要提前设置寄存器来进行一些参数的配置。寄存器每个位置的意义可以参考芯片给出的参考手册。注意各家名词的定义可能有不同之处,因此需要自己适当理解本来我想每个寄存器都介绍一遍,但后来想想,首先STM32F4和STM32F1都不一样,更不用说什么国产芯片了,因此还是记录模式吧。

STM32F4XX的DMA_SxCR寄存器(stream x configuration register),用来配置DMA

一、使能

DMA的控制寄存器一定会有的一个信号EN。这个信号一般是低电平(0)无效,高电平(1)有效,可以通过软件进行控制。高电平代表DMA开始工作,而EN信号在特定情况下(例如DMA信号传输结束、产生错误或者数据模式不匹配)都会被硬件主动清0。通常来说大部分别的寄存器的值在EN高电平的时候是无法被修改的,只有在EN低电平的时候才可以通过软件进行修改。

二、传输模式

不同传输模式

DMA的传输模式从目的地来区分有外设-内存,内存-外设,内存-内存,从传输方式区分有循环传输、直接传输(单个/突发)和双缓冲传输。但是奇怪的是为什么内存到内存全是fobidden呢?这时候我们翻手册回到第二章Memory and bus architecture,找到这张系统架构图。

可以看到AHB periph1都有两根线,而SRAM只有一根线进出,那么对于本身传输速率极高的CPU,如果想靠一根线搬进再搬出,那是基本不可能的事情,因此也是理所当然 的被forbidden了。

循环传输

传输的地址会随着数据传输自动增加,到地址末端的时候,他会自动回到地址开头,优点是非常省心,缺点是需要一直占着总线。

直接传输

直接传输又分为Single和Burst,直接传输会有个倒数标志,告诉DMA还有多少个数据要搬。

这里面我们重点介绍burst,Burst transfer翻译成中文就是突发传输,配置的时候INCR全称是incremental burst of X beats。如果把DMA当成一家货运公司,那么Burst transfer的beat就是一次派多少辆车,burst就是一个车队,Increment offset是隔几个门牌号取货/送货,MSIZE设置的是每辆车能装多少东西,而FIFO就是临时存放数据的仓库。

1byte=8bit,halfword=2byte=16bit,word=4byte=32bit

以STM32F4的16byteFIFO为例:当每辆车可以装1byte的时候,车队一共有4、8、16三种选择。假设FIFO装满了16byte,可以叫4次4车、2次8车或者1次16车。如果FIFO只装了4byte,那我们叫一次4车的车队就行了,8和16会被禁止。从理论来讲8和16应该也是可以的。当每辆车可以装4byte的时候,叫一次4车的车队即可。

那么为什么要用burst传输呢?这边给出一个可能的解释。假设我们没有设置burst,那么数据就是接连不断的发送。这时候A地要发一个“大象”到B地,他占了8个byte,但传到4个byte的时候,突然打来一个电话(系统中断)总线传输停了,因为有人说要去B地拿货,结果在B地里只看到半个“大象”,那么很明显就会产生问题。那么burst的意义就是,我在传输完8个byte这一包之前,我不让别人打电话,我把目标地址和电话线都“占住”,这样就可以间接保证了数据的完整性。

双缓冲传输

双缓冲模式顾名思义,有两个传输目标地址来作为缓冲。一般在寄存器中先配置好两个目标地址,和第一个传输的目标,传输完成后它会自动切换地址。注意在传输过程中,是无法切换目标内存的。其实可以理解为在内存里面又开了两个FIFO,这样保证无论何时CPU都一定有提前放好的数据可以拿,不会出现CPU跑来内存却空手回去的情况。

剩下的想起来再写

作者:2403_87538712

物联沃分享整理
物联沃-IOTWORD物联网 » 芯游记之MCU:DMA详解

发表回复