直接存储器存取—基本原理、结构与应用(上)
发布时间:2008/5/28 0:00:00 访问次数:490
直接存储器存取(dma)控制器是一种在系统内部转移数据的独特外设,可以将其视为一种能够通过一组专用总线将内部和外部存储器与每个具有dma能力的外设连接起来的控制器。它之所以属于外设,是因为它是在处理器的编程控制下来执行传输的。值得注意的是,通常只有数据流量较大(kbps或者更高)的外设才需要支持dma能力,这些应用方面典型的例子包括视频、音频和网络接口。
一般而言,dma控制器将包括一条地址总线、一条数据总线和控制寄存器。高效率的dma控制器将具有访问其所需要的任意资源的能力,而无须处理器本身的介入,它必须能产生中断。最后,它必须能在控制器内部计算出地址。
一个处理器可以包含多个dma控制器。每个控制器有多个dma通道,以及多条直接与存储器站(memory bank)和外设连接的总线,如图1所示。在很多高性能处理器中集成了两种类型的dma控制器。第一类通常称为“系统dma控制器”,可以实现对任何资源(外设和存储器)的访问,对于这种类型的控制器来说,信号周期数是以系统时钟(sclk)来计数的,以adi的blackfin处理器为例,频率最高可达133mhz。第二类称为内部存储器dma控制器(imdma),专门用于内部存储器所处位置之间的相互存取操作。因为存取都发生在内部(l1-l1、l1-l2,或者l2-l2),周期数的计数则以内核时钟(cclk)为基准来进行,该时钟的速度可以超过600mhz。
每个dma控制器有一组fifo,起到dma子系统和外设或存储器之间的缓冲器的作用。对于memdma(memory dma)来说,传输的源端和目标端都有一组fifo存在。当资源紧张而不能完成数据传输的话,则fifo可以提供数据的暂存区,从而提高性能。
因为你通常会在代码初始化过程中对dma控制器进行配置,内核就只需要在数据传输完成后对中断做出响应即可。你可以对dma控制进行编程,让其与内核并行地移动数据,而同时让内核执行其基本的处理任务—那些应该让它专注完成的工作。
图1:系统和存储器dma架构。
在一个优化的应用中,内核永远不用参与任何数据的移动,而仅仅对l1存储器中的数据进行读写。于是,内核不需要等待数据的到来,因为dma引擎会在内核准备读取数据之前将数据准备好。图2给出了处理器和dma控制器间的交互关系。由处理器完成的操作步骤包括:建立传输,启用中断,生成中断时执行代码。返回到处理器的中断输入可以用来指示“数据已经准备好,可进行处理”。
图2:dma控制器。
数据除了往来外设之外,还需要从一个存储器空间转移到另一个空间中。例如,视频源可以从一个视频端口直接流入l3存储器,因为工作缓冲区规模太大,无法放入到存储器中。我们并不希望让处理器在每次需要执行计算时都从外部存储读取像素信息,因此为了提高存取的效率,可以用一个存储器到存储器的dma(memdma)来将像素转移到l1或者l2存储器中。
到目前为之,我们还仅专注于数据的移动,但是dma的传送能力并不总是用来移动数据。我们可以用代码覆盖的办法来提高性能,将dma的控制器配置为在执行前把代码送入l1指令存储器。代码往往存储于较大的外部存储器中,而根据需要有选择性的送入l1。
dma控制器的编程
让我们考察一下在定义dma活动的过程中可以有哪些选项。我们将从最简单的模型开始,并在此基础上过渡到更为灵活的模型,这反过来增加了设置的复杂度。
对于任何类型的dma传输,我们都需要规定数据的起始源和目标地址。对于外设dma的情况来说,外设的fifo可以作为数据源或者目标端。当外设作为源端时,某个存储器的位置(内部或外部)则成为目标端地址。当外设作为目标端,存储的位置(内部或者外部)则成为源端地址。
在最简单的memdma情况中,我们需要告诉dma控制器源端地址、目标端地址和待传送的字的个数。采用外设dma的情况下,我们规定数据的源端或者目标端,具体则取决于传输的方向。每次传输的字的大小可以是8、16或者12位。这种类型的事务代表了简单的1维(“1d”)统一“跨度”(unity stride)的传输。作为这一传输机制的一部分,dma控制器连续跟踪不断增加的源端和目标端地址。采用这种传输方式时,8位的传输产生1字节的地址增量,而16位传输产生的增量为2字节,32位传输则产生4字节的增量。上面的参数是基本的1d dma传输的设置参数。
我们只需要改变数据传输每次的数据大小,就可以简单地增加一维dma的灵活性。例如,采用非单一大小的传输方式时,我们以传输数据块的大小的倍数来作为地址增量。也就是说,若规定32位的传输和4个采样的跨度,则每次传输结束后,地址的增量为16字节(4个32位字)。
虽然1d dma得到了广泛的应用,但用处更大的则是2维(2d) dma,特别是在视频应用中。2d功能是我们所讨论的1d dma的
直接存储器存取(dma)控制器是一种在系统内部转移数据的独特外设,可以将其视为一种能够通过一组专用总线将内部和外部存储器与每个具有dma能力的外设连接起来的控制器。它之所以属于外设,是因为它是在处理器的编程控制下来执行传输的。值得注意的是,通常只有数据流量较大(kbps或者更高)的外设才需要支持dma能力,这些应用方面典型的例子包括视频、音频和网络接口。
一般而言,dma控制器将包括一条地址总线、一条数据总线和控制寄存器。高效率的dma控制器将具有访问其所需要的任意资源的能力,而无须处理器本身的介入,它必须能产生中断。最后,它必须能在控制器内部计算出地址。
一个处理器可以包含多个dma控制器。每个控制器有多个dma通道,以及多条直接与存储器站(memory bank)和外设连接的总线,如图1所示。在很多高性能处理器中集成了两种类型的dma控制器。第一类通常称为“系统dma控制器”,可以实现对任何资源(外设和存储器)的访问,对于这种类型的控制器来说,信号周期数是以系统时钟(sclk)来计数的,以adi的blackfin处理器为例,频率最高可达133mhz。第二类称为内部存储器dma控制器(imdma),专门用于内部存储器所处位置之间的相互存取操作。因为存取都发生在内部(l1-l1、l1-l2,或者l2-l2),周期数的计数则以内核时钟(cclk)为基准来进行,该时钟的速度可以超过600mhz。
每个dma控制器有一组fifo,起到dma子系统和外设或存储器之间的缓冲器的作用。对于memdma(memory dma)来说,传输的源端和目标端都有一组fifo存在。当资源紧张而不能完成数据传输的话,则fifo可以提供数据的暂存区,从而提高性能。
因为你通常会在代码初始化过程中对dma控制器进行配置,内核就只需要在数据传输完成后对中断做出响应即可。你可以对dma控制进行编程,让其与内核并行地移动数据,而同时让内核执行其基本的处理任务—那些应该让它专注完成的工作。
图1:系统和存储器dma架构。
在一个优化的应用中,内核永远不用参与任何数据的移动,而仅仅对l1存储器中的数据进行读写。于是,内核不需要等待数据的到来,因为dma引擎会在内核准备读取数据之前将数据准备好。图2给出了处理器和dma控制器间的交互关系。由处理器完成的操作步骤包括:建立传输,启用中断,生成中断时执行代码。返回到处理器的中断输入可以用来指示“数据已经准备好,可进行处理”。
图2:dma控制器。
数据除了往来外设之外,还需要从一个存储器空间转移到另一个空间中。例如,视频源可以从一个视频端口直接流入l3存储器,因为工作缓冲区规模太大,无法放入到存储器中。我们并不希望让处理器在每次需要执行计算时都从外部存储读取像素信息,因此为了提高存取的效率,可以用一个存储器到存储器的dma(memdma)来将像素转移到l1或者l2存储器中。
到目前为之,我们还仅专注于数据的移动,但是dma的传送能力并不总是用来移动数据。我们可以用代码覆盖的办法来提高性能,将dma的控制器配置为在执行前把代码送入l1指令存储器。代码往往存储于较大的外部存储器中,而根据需要有选择性的送入l1。
dma控制器的编程
让我们考察一下在定义dma活动的过程中可以有哪些选项。我们将从最简单的模型开始,并在此基础上过渡到更为灵活的模型,这反过来增加了设置的复杂度。
对于任何类型的dma传输,我们都需要规定数据的起始源和目标地址。对于外设dma的情况来说,外设的fifo可以作为数据源或者目标端。当外设作为源端时,某个存储器的位置(内部或外部)则成为目标端地址。当外设作为目标端,存储的位置(内部或者外部)则成为源端地址。
在最简单的memdma情况中,我们需要告诉dma控制器源端地址、目标端地址和待传送的字的个数。采用外设dma的情况下,我们规定数据的源端或者目标端,具体则取决于传输的方向。每次传输的字的大小可以是8、16或者12位。这种类型的事务代表了简单的1维(“1d”)统一“跨度”(unity stride)的传输。作为这一传输机制的一部分,dma控制器连续跟踪不断增加的源端和目标端地址。采用这种传输方式时,8位的传输产生1字节的地址增量,而16位传输产生的增量为2字节,32位传输则产生4字节的增量。上面的参数是基本的1d dma传输的设置参数。
我们只需要改变数据传输每次的数据大小,就可以简单地增加一维dma的灵活性。例如,采用非单一大小的传输方式时,我们以传输数据块的大小的倍数来作为地址增量。也就是说,若规定32位的传输和4个采样的跨度,则每次传输结束后,地址的增量为16字节(4个32位字)。
虽然1d dma得到了广泛的应用,但用处更大的则是2维(2d) dma,特别是在视频应用中。2d功能是我们所讨论的1d dma的