账号:
密码:
最新动态
产业快讯
CTIMES / 文章 /
直接记忆体存取的基础、结构与应用(1)
 

【作者: David Katz 與Rick Gentile】2007年05月18日 星期五

浏览人次:【12270】

嵌入式处理器的核心能够在单一周期内处理多重的运作,其中包括了计算、资料取得、资料储存、以及指标的增量与减量。除此之外,处理器核心还会藉由将资料从暂存档移入移出来对内外部记忆体空间之资料传输进行协调。


以上所述,听起来都很不错,但是在现实状况中,假如资料可以搬移而又不会一直对执行传输的核心产生干扰时,这样才能够在该应用领域中够达到最佳化的效能。而这就是直接记忆体存取(DMA)能够发挥作用的地方。处理器需要DMA的能力,以便使核心能够从内外部记忆体与周边之间,或是记忆体空间之间(记忆体DMA,或是”MemDMA )的资料传输作业中被解放出来。


DMA控制器有两种主要的类型。 「周期盗取(Cycle-stealing)」DMA会利用多余的(空闲,idle)核心周期来执行资料的传输。对于处理负担很沉重的系统而言,例如多媒体流(multimedia flows),这不是一个可行的解决方案。相对的,使用DMA控制器在核心之外独立运作会来得更加有效率。


这点为何如此重要?我们可以设想一种情况,假如处理器的视讯埠具有先进先出(FIFO)功能,在每次有资料样本可以取得时就必须被读取。在这个状况下,核心将会在每一秒钟内被中断上千万次。还不光只有这些中断而已,核心还必须对目标记忆体执行等量的写入程序。对于在这项任务上的每个核心处理周期来说,在处理程序的回路中将会有对等的周期因而损失掉。


就如同理论上所听过​​的DMA一样,以PC为基础的软体设计工程师在转移到嵌入式领域的过程中,对于在应用装置上的资料搬移必须仰赖DMA控制器是颇感迟疑的。之所以会有这样的不情愿,通常是源自于一种既定印象─将DMA纳入设计中会增加潜在的编程模型复杂度─所造成。然而我们的目的就是要让各位放松心情,告诉各位DMA为何能够真正的帮上忙。在这一系列的文章中,我们将会把焦点放在DMA控制器上面,接着告诉各位如何以DMA来将效能最佳化,最后对于DMA控制器作为整体架构之一部分时,要如何最适当的加以管理提出一些想法。


让我们稍微离题一下,先来讨论记忆体空间(memory space)这个术语。嵌入式处理器具有阶层式记忆体架构(hierarchical memory architecture ),能够致力于对数个层级的记忆体,利用不同的大小与效能等级来加以平衡。最接近核心处理器的记忆体(称为Level 1,或是L1记忆体),是以核心时脉的全速来运作的。以「最接近」来形容并不夸张,因为在矽晶片中,L1记忆体在实体上确实是很贴近核心处理器,这样才能获得最快的存取和运作速度。L1记忆体最常被划分为指令区块以及资料区块,以便有效的利用记忆体汇流排之频宽。


当然,L1记忆体的大小也必须有所限制。对于需要较大编码大小的系统而言,额外的内建与外接记忆体都是可以利用的─当然也会增加延迟。较大的内建记忆体被称为Level 2(L2)记忆体,而外接记忆体我们则称之为Level 3(L3)记忆体。 L1记忆体的大小通常都有数十个kBytes,L2内建记忆体则是以数百个kByte来计算,至于L3记忆体则往往都是以megabyte计算。


现在回到我们原本的讨论主题上。 DMA控制器是一个独特的周边,专门用来在系统中搬移资料。试想一个控制器,藉由一组专用的汇流排使内部和外部记忆体与具有DMA功能的周边相互连结。就意义上而言,它是一组处理器能对其加以编程,以便执行传输的周边。使记忆体与选定之周边相互接合为其独特之处。很明显的,只有资料流动十分明显(每秒kBytes或是更大)的周边才需要具备有DMA功能。最佳的范例就像是视讯、音讯以及网路介面等。频宽较低的周边也可以具备有DMA功能,这将可以使核心减少一些介入上的负担,并且对这些介面上的资料传输给予协助。


通常,DMA控制器会包含有位址汇流排(address bus)、资料汇流排(data bus)、以及控制暂存器(control registers)。有效率的DMA控制器会具备有能够自行对任何所需资源提出存取要求的能力,而不需要处理器本身的介入。它必须要有产生中断的能力。最后,它必须要能够在控制器内部计算位址。


在一个处理器当中可能包含了多个DMA控制器。每个控制器都具有多重DMA通道以及多重汇流排,用以直接和记忆体插槽与周边做连结,如(图一)中所示。在许多的高效能处理器中会拥有两大类型的DMA控制器。第一种类型通常称为系统DMA控制器(System DMA Controller),可以存取所有的资源(周边以及记忆体)。这类型控制器之周期数(cycle count)是以高达133 MHz频率(以ADI的Blackfin处理器为例)之系统时脉(SCLKs)来加以计算的。第二种类型称为内部记忆体DMA控制器(IMDMA),是专门为了在内部记忆体之间进行存取之用。由于存取动作都在内部(L1到L1,L1到L2,或是L2到L2)进行,所以周期数是以可以超越600 MHz速率之核心时脉(CCLKs)来加以计算的。



《图一 系统与内部存储器DMA架构》
《图一 系统与内部存储器DMA架构》

每个DMA控制器都有一组FIFOs,可以在DMA子系统与周边或是记忆体之间做为缓冲之用。对于MemDMA而言,在转换时的来源端与目的端都存在有FIFO。当资源处于忙碌状态,以致于转换无法完成时,FIFO能藉由提供可以存放资料之位置来改善效能。


由于多数人都会在编码初始化阶段就对DMA控制器做设定,因此核心应该只需要在整组资料的转换完成之后才对中断予以回应。当核心还在执行其基本的处理任务时─这才应该是真正需要投注焦点的工作─就应该对DMA控制器加以编程,使其能够与核心平行式的搬移资料。


在经过最佳化的应用装置上,核心绝对不用去处理任何搬移资料的工作,除了在L1记忆体上的存取。核心并不需要等待资料送达,因为在核心要存取这些资料之前,DMA引擎早就已经将其准备好了。 (图二)中所示为在处理器与DMA控制器之间的典型互动关系。当中断产生时,分配到处理器的步骤都是有关于传输的设定、中断的启动、以及程式码的执行等。而回返至处理器上的中断输入可以用来发出资料已经准备接受处理的信号。



《图二 DMA控制器》
《图二 DMA控制器》

资料除了在各个周边来回搬移之外,也需要在各个记忆体空间来回的搬移。举例来说,视讯源可能会从视讯埠直接流向L3记忆体,这是因为工作的缓冲区大小太大,以致于无法存放于内部记忆体中。我们不希望在每次需要执行运算作业时,处理器都还要从外部记忆体去取得像素,因此记忆体对记忆体(memory-to-memory)DMA(MemDMA)可以用更有效率的存取时间将像素送至L1或L2记忆体当中。 (图三)所示为一些典型的DMA资料流。


《图三 典型的DMA数据流》
《图三 典型的DMA数据流》

到目前为止我们都是著眼于资料的搬移,但是DMA传输并不一定都会牵涉到资料。我们可以使用code overlays,设定DMA控制器将程式码在未执行之前搬移至L1指令记忆体当中,借此来改善效能。程式码通常会存放于较大的外部记忆体当中,并且在有需要时才会被选择性的载入L1记忆体。


对DMA控制器加以编程

现在让我们来看看,在指定DMA的动作时有什么选项可以使用。我们将会从最简单的模型开始,然后建立起较具弹性化的模型,并且依序增加设定上之复杂度。


对于任何型态的DMA传输来说,我们总是需要为资料指定启始来源以及目标位址。在周边DMA的情况中,该周边的FIFO若不是担任来源就是担任目标。当该周边担任来源时,记忆体所在位置(内部或外部)就担任目标位址。当周边担任目标时,记忆体所在位置(内部或外部)就担任来源位址。


在最简单的MemDMA的情况中,我们必须要将来源位址、目标位址以及欲传输字串的数量告知DMA控制器。使用周边DMA时,只需要指定来源或是目标,视传输的方向而定。每次传输的字串大小可以是8、16、或32位元任一组。这种类型的处理代表了具有一致性「 步幅」(stride)的简单一维(1D)转换。 DMA控制器作身为这种转换中的一部份,会随时注意来源与目标位址的增加量。藉由一致性的步幅,8位元传输的位址增加量为1位元组,16位元传输的增加量为2位元组,32位元的增加量为4位元组。由以上的参数可以设定出基本的1D DMA传输,如(图四)中所示。


《图四 1D DMA的范例:(a)具有一致性的步幅,(b)具有非一致性的步幅》
《图四 1D DMA的范例:(a)具有一致性的步幅,(b)具有非一致性的步幅》

\虽然1D DMA的能力已经受到广泛的使用,但是二维(2D)的能力其实是更具利用价值的,特别是在视讯应用领域方面。 2D的特点就是我们所讨论1D DMA之特点的直接延伸。除了XCOUNT与XMODIFY值之外,我们也可以对相关的YCOUNT以及YMODIFY值进行编程。最简单的方法就是把2D DMA想像成一个巢状回路,内部回路是藉由XCOUNT与XMODIFY来加以指定,而外部回路则是以YCOUNT以及YMODIFY加以指定。因此1D DMA就可以只当作是如下形式的2D传输中之「内部回路」:


for y = 1 to YCOUNT /* 2D with outer loop */


for x = 1 to XCOUNT /* 1D inner loop */


{


/* Transfer loop body goes here */


}


XMODIFY会决定每当XCOUNT减量时,DMA控制器所采用的步幅值,而YMODIFY则会决定每当YCOUNT减量时所要采用的步幅值。就如同XCOUNT与XMODIFY的情况一样,YCOUNT会以传输的数量来加以指定,而YMODIFY则是以位元组的数量来指定。很明显的,YMODIFY可以是负数,以便使DMA控制器能够在缓冲区启始位置的周边绕返。我们将会对这个特点做一简短的探讨。


对于周边DMA来说,传输的「 记忆体端」不是1D就是2D。然而,在周边端永远都会是1D传输。唯一的限制就是DMA的每一端(来源与目标),其被传输的位元组总数必须要相同。举例来说,假如我们要从三个10位元组的缓冲区将资料传给一组周边,该周边就必须使用任何有被支援的传输宽度以及可取得的传输计数值所可能产生的组合,将其传输设定为30个位元组。


MemDMA提供了多一点的弹性。举例来说,我们可以设定1D对1D传输,1D对2D传输,2D对1D传输,当然还有2D对2D传输,如(图五)所示。唯一的限制就是DMA传输区块的每一端,其被传输的位元组总数必须要相同。


《图五 内存DMA的可能设定》
《图五 内存DMA的可能设定》

现在我们来看看一些DMA设定的范例:


范例 1

假设有一组 4像素(每列)× 5列的阵列,具有位元组大小(byte-sized)的像素值,安排如(图6a)所示。



《图六 范例 1 中的来源与目标数组》
《图六 范例 1 中的来源与目标数组》

然这些资料是以矩阵方式显现,但是就像图6b中所示,这些资料是连串出现在记忆体中的。


现在我们想要利用DMA控制器建立如(图六c)中所示的阵列。


在这个传输中的来源与目标DMA暂存器之设定如下:


























来源

目标

XCOUNT=5

XCOUNT=20

XMODIFY=4

XMODIFY=1

YCOUNT=4

YCOUNT=0

YMODIFY=-15

YMODIFY=0

来源与目标字串的传输大小为每次传输1位元组。


让我们来完成这个处理程序。在这个范例中,我们可以使用MemDMA并且采用2D对1D传输设定。由于来源是2D,所以显然来源通道的XCOUNT与YCOUNT值分别为5与4,因为阵列大小就是4像素/列 × 5列。因为我们将会使用1D传输来将目标缓冲区填满,所以我们只需要将目标端的XCOUNT与XMODIFY加以编程即可。在这个情况下,XCOUNT的值设为20,因为这就是将要被进行传输的位元组数目。目标端的YCOUNT值就是0,而YMODIFY也是0。可以看到计数值将会遵循我们稍早所讨论过的规则(例如4 × 5 = 20位元组)。


现在让我们来谈谈用于来源缓冲区上之XMODIFY与YMODIFY的正确值。我们希望取得第一个值(0 × 1),并且跳过4个位元组到下一个0 × 1的值。此步骤将会重复五次(来源XCOUNT = 5)。来源XMODIFY的值是4,因为该数值就是控制器为了取得下一个像素(包括第一个像素)所跳过的位元组数目。 XCOUNT值会在每次搜集到一个像素时减1。当DMA控制器达到第一列的终点时,XCOUNT值会降到0,同时YCOUNT则会减1。接着在来源端上的YMODIFY值需要将位址指标(address pointer)带回到阵列中的第二元素上(0 × 2)。当此发生的瞬间,位址指标还仍然是指在第一列(0 × 1)的最后一个元素上。在阵列中由该点往回数至第一列的第二个像素,总共会通过15个元素。因此来源YMODIFY为 -15。


假如核心在完成这个传输时没有借助DMA控制器的协助,那么它将会为了对每个像素进行读取与写入而消耗掉极可贵的周期。此外,核心还需要注意来源与目标端的位址,以及对每个传输的步幅值进行追踪。


以下是一个更为复杂,关于2D对2D传输的范例:


范例2

假设我们现在从具有0xFF值之边界的阵列开始,如(图七)中所示。



《图七 范例 2中的来源与目标数组》
《图七 范例 2中的来源与目标数组》

我们希望只将来源矩阵(以粗笔画显示)的内部方块保留下来,但是也希望能够将矩阵旋转90度,如(图七)中所示。


以下的暂存器设定会将这个范例中的传输产生出来,而我们也会解释其原因。























来源???????????????

目标

XCOUNT =4?

XCOUNT =4

XMODIFY = 1

XMODIFY = 4

YCOUNT = 4

YCOUNT = 4

YMODIFY= 3

YMODIFY= -13


首先,我们必须要决定如何在来源阵列中存取资料。当DMA控制器从来源阵列中读取每个位元组的同时,目标端也将会以每次一个位元组的方式建立起输出阵列。


我们要如何开始呢?让我们先看看我们想要搬移至输入阵列中的第一个位元组。此处以斜体字表示为(0 × 1)。这对于我们在选择来源缓冲区的启始位址时,将会很有帮助。接着我们希望在跳过”边界”位元组之前能够连续读取接下来的三个位元组。在这个范例中,传输的大小是被假设为 1位元组。


由于控制器会在跳过某些位元组而移动至阵列中的下一列之前,先读取同一列中的四个位元组,所以来源XCOUNT值为 4。因为控制器会在其搜集到0 × 2、0 × 3、以及0 × 4的同时将位址加 1,因此XMODIFY值为 1。当控制器完成了第一列之后,来源YCOUNT值会减 1。因为我们有四列要传输,所以来源YCOUNT值为 4。最后,来源YMODIFY值为 3,这是因为就如同先前我们所讨论过的,当XCOUNT由 1变成 0之后,位址指标不会以XMODIFY值增加。设定MODIFY值为3可以确保下次所要取得的是0 × 5。


在传输的目标端,我们将要再次的把0 × 1位元组之位置加以编程,作为初始的目标位址。因为从来源位址所取得的第二个位元组是0 × 2,所以控制器接着必须要将这个值写入到目标位址。如同图7中所示的目标阵列,其中的目标位址必须先增加 4,而这个值也正是用来定义目标XMODIFY的值。由于目标阵列的大小为4 × 4,因此目标XCOUNT以及YCOUNT的值也都是4。唯一剩下的值就是目标YMODIFY。要算出这个值,我们必须要先算出有多少目标位址的位元组被从搬回至阵列中。当目标YCOUNT经过第一次减量之后,目标位址会指向0 × 4的值。最后所计算出的目标YMODIFY值为 –13,其可以确保0 × 5的值被写入至目标缓冲区的所指定位置。


在下一篇文章中,我们将会更深入探讨DMA,讨论两大主要传输分类:以暂存器为基础(Register-based)与以叙述元为基础(Descriptor-based),以及何时该使用何种形式。


文章后之资料:::


属性(人物):::


属性(产业类别):::RED


属性(关键字):::DMA,记忆体


属性(组织):::ADI


属性(产品类别):::


属性(网站单元):::ZEIE


相关文章
具备超载保护USB 供电ISM无线通讯
以GMSL取代GigE Vision的相机应用方案
运用PassThru技术延长储能系统寿命
巨磁阻多圈位置感测器的磁体设计
为新一代永续应用设计马达编码器
comments powered by Disqus
相关讨论
  相关新闻
» ST汽车级惯性模组协助车商打造具成本效益的ASIL B级功能性安全应用
» 调研:2024年第一季全球晶圆代工复苏缓慢 AI需求持续强劲
» 西门子Solido IP验证套件 为下一代IC设计提供端到端矽晶品质保证
» 意法半导体RS-485收发器兼具传输稳定性与速度 适用於工业自动化、智慧建筑和机器人
» 工研院携手联发科开创「边缘AI智慧工厂」 创新整合平台降低功耗50%


刊登廣告 新聞信箱 读者信箱 著作權聲明 隱私權聲明 本站介紹

Copyright ©1999-2024 远播信息股份有限公司版权所有 Powered by O3  v3.20.1.HK85O3PWPIWSTACUKO
地址:台北数位产业园区(digiBlock Taipei) 103台北市大同区承德路三段287-2号A栋204室
电话 (02)2585-5526 #0 转接至总机 /  E-Mail: webmaster@ctimes.com.tw