Fork me on GitHub
0%

DMA

基础

DMA:Direct Memory Access,直接内存访问。

DMA是计算机系统中一种数据传输的技术,允许将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输,而整个过程不需要CPU的直接干预。用户需要做的是根据实际需求,配置DMA控制器,一旦使能控制器数据将自动根据配置进行传输。解放出来的CPU可以去做其它的事情,极大的提高了效率。需要注意的是DMA只是不再占用CPU,但仍需要占用总线

主要特征

传输模式

  • Burst Mode

    Burst传输,可以翻译为突发传输或者是连续传输。是指在同一行中相邻的存储单元连续进行数据传输的方式,只要指定起始地址和突发长度(Burst lengths,可以理解为跨度),控制器就会依次自动对后面相同数量的存储单元进行读/写操作,而不需要控制器连续提供列地址。DMA仅在完成整个数据传输后将总线移交给CPU。同时,如果 CPU 需要总线,它必须保持IDLE并等待数据传输。

  • Cycle Stealing Mode

    单字节传输。DMA 在传输每个字节后将总线的控制权交给 CPU。它不断发出总线控制请求,传输一个字节并返回总线。这样一来,如果 CPU 需要总线来执行更高优先级的任务,则不必等待很长时间。

  • Transparent Mode

    DMA 仅在 CPU 执行不需要使用总线的指令时传输数据。该模式传输数据块所需的时间最多,但就整体系统性能而言,它也是最有效的模式。 DMA 传输在时间上是自由的,而缺点是硬件需要确定 CPU 何时不使用系统总线比较复杂。

传输方式

DMA传输的本质就是实现数据从一个内存区域到另一个内存区域的拷贝,主要包含四种情况:外设到内存;内存到外设;内存到内存;外设到外设。

传输结构

寄存器模式

处理器直接对DMA控制寄存器进⾏编程来启动传输。在寄存器模式下⼜分为两种⼦模式组成:⾃动缓存模式和停⽌模式。

在⾃动缓存模式中,当⼀个传输块传输完毕,控制寄存器就⾃动重新载⼊其最初的设定值,同⼀个DMA进程重新启动。这构成了⼀个“循环缓冲器”,因为当⼀个值被写⼊到缓冲器的最后⼀个位置上时,下⼀个值将被写⼊到缓冲器的第⼀个位置上。⾃动缓冲 DMA 使⽤场景:对性能敏感的、存在持续数据流的应⽤。DMA控制器可以在独⽴于处理器其他活动的情况下读⼊数据流,然后在每次传输结束时,发出中断。

停⽌模式 DMA 与⾃动缓冲型类似,区别在于各寄存器在DMA结束后不会重新载⼊,因此整个DMA传输只发⽣⼀次。使⽤场景:⾮定期地将数据块从⼀个位置转移到另⼀个位置、某些事务的⼀次性传输。

描述符模式

基于描述符的 DMA 要求DMA 通道需要⼀组称为 DMA 描述符的参数,该参数存储在存储器中。每个描述符包含特定 DMA 传送序列所需要的所有信息,⽐如 数据块的起始地址、传送的数据量、其他各种控制信息、指向下⼀个描述符的指针。

该模式可以更好的减少中断的产生,因为可以配置一个descriptor链,按照链上的顺序进行传输(4+1+2+x+x)

传输流程

image

cpu通过配置DMA各个寄存器,使其具有相应的功能 ; DMA通过总线从device中取出数据,在通过特有的DMA通道传输给DDR

DMA系统框图(STM32)

image

配置过程

  1. 配置数据传输的源和目标地址

  2. 配置传输数量

  3. 配置数据位宽(8bit / 16bit / 32bit)

  4. 配置功能:数据传输方向、循环模式以及源和目标地址是否自增

  5. 配置中断(全部完成 / 完成一半 或其它所支持的方式)

  6. 使能DMA

请求及响应流程

  1. (外设->DMA控制器)请求DRQ(DMA Request)。当设备需要通过DMA通道传输数据,首先外设需要向DMA控制器发送DMA请求。
  2. (DMA控制器->CPU)保持请求 HRQ(Hold Request)。DMA 控制器向 CPU 发送保持请求 并等待 CPU 断言 HLDA 信号。
  3. (CPU->DMA控制器)保持确认 HLDA(Hold Acknowledgment)。CPU所有数据总线、地址总线和控制总线三态化并释放总线控制权,回复HLDA 信号允许DMA控制器接管总线
  4. (DMA控制器->外设)回复DACK(DMA Acknowledgment)。DMA控制器向发出DRQ信号的外设的回应,表示收到请求和正在进行处理。

注意事项(重要)

  1. DMA需要使用物理地址。因为编程使用的是虚拟地址,所以配置DMA时必须将虚拟地址转化成物理地址
  2. DMA启动前刷Cache。因为程序使用虚拟地址,而且一般使用Cached地址,所以虚拟地址中的内容与其物理地址上的内容不一定一致,所以在启动DMA传输前一定要将该地址的Cache刷新,即写入主存。
  3. 地址对齐且尽量一次申请一大块内存保证连续。由于系统产时间使用之后可能产生内存碎片,申请到的空间可能不连续导致错误,如果不连续就需要把这段内存分成几段让DMA完成传输
  4. 性能瓶颈。对于DMA控制器来讲,通常有多个通道可以配置,不同的通道可以并发传输。虽然多通道可以同时工作但是总线只有一条,因此在特定时刻实际只有一个通道能在总线上传输数据。不同的MCU对于DMA通道传输的调度策略有所不同,可能是先到先调度、也可能是基于channel的优先级进行调度
  5. 某些设备内部可能有自己的专用DMA,硬件上与通用DMA是一致的,但是在速度、可靠性上有所提高。通用DMA:burst可能更小一些;专用DMA:burst可以传输的更大一些 。DMA尽量按照最大数据量进行传输(某些设备除外,串口可能就是按照1byte传输),但是对于5byte可以按照 4 +1 的方式传输

参考资料

  1. DMA
  2. DMA原理,步骤超细详解,一文看懂DMA
  3. DMA中的四种控制信号:DRQ、DACK、HRQ、HLDA
  4. STM32中文手册