嵌入式CPU中DMA的意义是什么?


17

我最近正在使用mbed(LPC1768)做一个项目,使用DAC输出各种波形。我阅读了数据表的各个部分,并讨论了许多外设如何使用DMA。这似乎很有用,但是在进一步阅读后,我发现DMA使用的数据总线与cpu相同(我认为这是正常的)。这是否意味着在DAC获取数据时CPU无法与任何存储器交互?另外,由于DAC没有缓冲区(据我所知),因此必须经常进行DMA,DMA的意义何在?如果CPU无法执行内存事务,它可以做什么?


8
我建议您查看一下CPU的功能以及它是否可以执行除访问内存以外的任何其他操作。我听过一些的CPU,可以做之类的东西决定或计算,不知道这是共同所有..
PlasmaHH

CPU应该花时间将数据传输到I / O端口还是将任务委托给专用设备?
StainlessSteelRat

是的,CPU可以做其他事情,但是在嵌入式系统中,CPU可能会花费大量时间与外围设备(尤其是I / O端口)接口。仅为DMA提供额外的数据总线是否更有意义?还是通常不需要?您想要增加总线的情况是,当您尝试提高硬件的极限时,我认为那是您无论如何都希望通过DMA进行交易?
BeB00

1
举个简单的例子,假设您想将大量信息打印到串行端口。您可以坐下来等待每个字节发送(慢速),将其复制到缓冲区,然后在端口就绪(大量上下文切换=慢速)时使用CPU上的中断发送每个字节,或者将其复制到一个缓冲区,让DMA控制器在CPU忙于执行其他操作时将数据超时(可能更快)。
汤姆·卡彭特

2
一次看到EDN的封面,上面有一个男人穿着一双巨大的三英尺长的鞋子的画图,并有一个标题:“如果是鞋子,那就穿。” 关键是,如果一个零件执行了您不需要的十件事,而您需要做的一件事,并且价格,占用空间和功耗预算都合适,那么您应该只使用它,而不必浪费时间去寻找东西功能较少。
所罗门慢速

Answers:


17

我发现的LPC1768数据表带有以下引号(强调我的意思):

AHB多层矩阵上的八通道通用DMA控制器(GPDMA),可与SSP,I2S总线,UART,模数和数模转换器外设,定时器匹配信号一起使用,并用于存储器到内存转移。

分离式APB总线可实现高吞吐量,而CPU和DMA之间的停顿很少

第6页的框图显示了AHB矩阵之间具有多个通道的SRAM,以下引用对此表示支持:

LPC17xx总共包含64 kB片上静态RAM存储器。其中包括可由高速总线上的CPU和DMA控制器访问的主32 kB SRAM,以及位于AHB多层矩阵上独立从端口上的两个附加16 kB SRAM块。这种架构允许CPU和DMA访问分布在三个可以同时访问的独立RAM上

以下引用进一步证明了这一点:

GPDMA支持外设到内存,内存到外设,外设到外设以及内存到内存的事务。

因此,您可以从单独的SRAM块之一或其他外围设备将数据流传输到DAC,同时将主SRAM用于其他功能。

这种外围设备DMA在内存接口非常简单的较小部件中很常见(与现代Intel处理器相比)。


啊,谢谢,我没有意识到这是可能的,我对DMA有点陌生。这是否意味着在DAC访问单独的SRAM时,CPU可以访问外设?
BeB00

1
是的-这正是AHB矩阵的用途。它允许不同的控制器(CPU,DMA,某些外围设备,如以太网和USB)同时访问不同的事物。这就是为什么存在多个通往SRAM的“端口”的原因。
戴维(David

是的,由于并行存储库,在这些便宜的小生物中的AHB提供了疯狂的存储带宽:您可以拥有以太网,USB2,一切都以最大吞吐量运行,而CPU甚至都没有注意到……
peufeu

同样,拇指代码可以将2条指令放在一个32位字中,因此,在进行数学或主要涉及寄存器的运算时,cpu可能不需要经常访问总线...另一方面,我认为M3和M4可以由于具有多个总线,每个时钟(指令和数据)执行几次内存访问。
peufeu

30

总而言之,DMA使CPU能够以其本机速度有效运行,而外设可以以其本机速度有效运行。该示例中的大多数数字都是虚构的。

让我们比较两个选项以定期从ADC收集数据:

  1. 您可以将ADC设置为中断的一部分(定期或其他方式)
  2. 您可以创建一个缓冲区,并告诉DMA将ADC读数传输到该缓冲区。

让我们将1000个样本从ADC传输到RAM。

使用选项1:每个样本都有

  • 进入中断花费了12个周期
  • 读取ADC
  • 存放在ram
  • 退出中断花费了12个周期

假设这个中断功能是76条指令,假设单周期执行(最佳情况),整个例程长100条指令。这意味着选项1将花费100,000个CPU时间周期执行。

选项2:将DMA配置为收集1000个ADC样本。假设ADC具有来自计时器计数器的硬件触发。

  • ADC和DMA向RAM传输1000个采样数据
  • DMA在1000个采样后中断您的CPU
  • 进入中断花费了12个周期
  • 代码发生(假设它告诉DMA覆盖RAM)
  • 退出中断花费了12个周期

假装整个中断(带有进入和退出开销)是100个单周期指令。使用DMA,您只需花费100个周期即可保存相同的1000个样本。

现在,每次DMA访问总线时,是的,CPU和DMA之间可能会发生争执。甚至可能迫使CPU等待DMA完成。但是,等待DMA完成要比将CPU锁定来维修ADC短得多。如果CPU核心时钟为2x总线时钟,则CPU可能会浪费几个核心周期来等待DMA完成。这意味着您的传输有效执行时间在1000个周期(假设CPU从不等待)到9000个周期之间。仍然比100,000个周期更好。


2
重要的是要注意,RAM并不是CPU可以存储数据的唯一位置。通常,CPU在处理数据之前会将数据从RAM加载到寄存器中。
阿隆(Aron)

是的,完全正确。我的例子纯粹是一个粗略的草图。
pgvoorhees

许多微控制器还具有多层总线,因此可以进行并行操作。例如:adc-> ram和flash->同时注册。另外,许多指令的时间都超过1个时钟,因此DMA有足够的时间。
Jeroen3'9

9

如果在给定的周期上处理器和DMA控制器需要访问同一条总线,则一个或另一个将必须等待。但是,许多系统包含具有独立总线的多个内存区域以及一个总线“桥”,该桥将允许CPU访问一个存储器,而DMA控制器访问另一个存储器。

此外,许多CPU可能不需要在每个周期访问存储设备。如果CPU通常只需要在三个周期中的两个周期内访问内存,则低优先级DMA设备可能能够利用内存总线空闲时的周期。

即使在每个DMA周期都会导致CPU停顿一个周期的情况下,但是,如果数据到达的速度足够慢,以至于CPU应该能够在传入的数据项之间执行其他操作,则DMA可能仍然非常有用。 ,但速度足够快,因此需要将每个项目的开销降至最低。例如,如果SPI端口以每16个CPU周期以1字节的速率向设备馈送数据,则为每次传输中断CPU可能会导致它花费几乎全部时间进入和退出中断服务程序,而没有中断做任何实际的工作。但是,使用DMA,即使每次DMA传输导致CPU停顿两个周期,开销也可以减少到13%。

最后,某些CPU允许在CPU处于睡眠状态时执行DMA。使用基于中断的传输将要求系统为每个传输的数据单元完全唤醒。但是,使用DMA时,睡眠控制器有可能在每次输入一个字节时向存储控制器提供几个时钟,但让其他所有对象保持睡眠状态,从而降低了功耗。


1
诸如LPC1768之类的Cortex-M部件具有从闪存到指令解码器的独特存储路径,因此实际上寄存器到寄存器的操作可能意味着CPU可以在需要访问数据存储器的时间之间执行多个指令。
克里斯·斯特拉顿

5

作为程序员,DMA是向与支持它的外围设备之间传输数据的一种选择。对于通过串行外围设备(如SPI或UART)移动大型缓冲区或从ADC收集大量样本的经典示例,您可以通过以下三种方法移动数据:

  1. 轮询方法。在这里等待寄存器标志,以允许您移入/移出下一个字节。问题是您在等待CPU的同时阻止了CPU的所有执行。或者,如果您必须在操作系统中共享CPU时间,则传输将大大减慢。

  2. 中断方法。在这里,您编写一个中断服务程序(ISR),该程序在每次字节传输时都执行,并在ISR中编写代码以管理传输。这会提高CPU效率,因为CPU仅在需要时才会为您的ISR提供服务。除ISR以外,其他所有时间均可免费使用。从传输速度来看,ISR也是进行传输的较快选择之一。

  3. DMA。您可以使用源/目标指针,传输次数和关闭状态来配置DMA。它会占用总线周期和CPU时间来完成传输,同时CPU可以自由地做其他事情。您可以配置标志或中断来指示何时完成传输。通常触摸速度比ISR快,并且通常是最快的传输选项。

作为程序员,我更喜欢DMA,因为它最容易编码,并且本质上是进行传输的最快技术。通常,您只需要为源/目标指针和要进行的传输数量配置几个寄存器。与IDMA代码相比,我在ISR代码上花费的时间要多得多,因为ISR代码需要关键的设计技能,并且必须进行编码,测试,验证等。DMA代码要小得多,我必须自己编写代码相对来说是微不足道的,并且在讨价还价中我获得了最大的传输速度。

以我的经验,最近使用Atmel SAM3 / 4处理器,DMA的运行速度比我自己制作的高效ISR快。我有一个应用程序,每5毫秒从SPI读取一堆字节。后台任务中发生了很多浮点数学运算,因此我希望CPU对于这些任务尽可能地自由。最初的实现是ISR,然后我转向DMA进行比较,并尝试在两次采样之间购买更多的CPU时间。传输速度的增益略有提高,但只有一点点提高。在o-scope上几乎无法测量。

这是因为在我所看到的最新微处理器上,ISR和DMA几乎以相同的方式运行-它们按照所需的CPU周期进行操作,而DMA与CPU进行的操作基本上与我在高效ISR中编码的方式相同。

在极少数情况下,我看到外设具有自己的RAM区域,而DMA仅可访问这些区域。这是在以太网MAC或USB上。


3

DMA最有可能在这里使用,因此DAC可以具有一些常规定时,可以通过以某个已知间隔更改模拟输出来生成波形。

是的,如果这是共享巴士,那么...您必须共享。

CPU并不总是使用总线,因此与DMA引擎共享有时是个好主意。当然,这意味着优先级会涉及到,有时只是先到达优先级(例如,在资源前面有一个命令fifo,然后按照请求到达的顺序对请求进行fifo,是的,这不一定是确定性的)。在这种情况下,您可能希望dma优先于cpu,以便对时间敏感的事物(如DAC或ADC)具有确定的时序。取决于他们选择如何实施。

人们有时会错误地认为dma是免费的。它是否仍会消耗总线时间,如果与cpu共享(它最终是在与cpu可以与之交谈的资源进行通讯时),则cpu和/或dma会被推迟,因此cpu仍然必须等待一些时间。有时,在某些实现中(可能不是您的微控制器),CPU会完全推迟,直到DMA完成为止,而CPU会持续一段时间。只是取决于实现。它的自由之处在于,不必为了某些事件而持续不断地中断CPU或轮询或屏住呼吸来馈送数据。创建dma的下一个缓冲区可能要花费一些时间。它确实必须注意dma传输是否完成并进行处理,但是现在不必说每个字节而是多个字节,而是一些数据块。

没有一个普遍的答案。“取决于” ...取决于您所使用的特定物品的特定设计。即使在一个芯片/板/系统设计中,也可能有多个dma引擎,没有理由假定它们都以相同的方式工作。对于每个实例,您都必须弄清楚,但是不幸的是,他们经常没有记录或记录得足够好。因此,如果您担心的话,可能必须创建一些实验。


注意嵌入与它无关。dma的要点是通过可能为cpu进行工作来获得性能,因此它不必具有代码,并利用通常未使用的总线周期来进行工作。同样适用于您在正确的时间馈送数据的问题,理想情况下没有cpu开销。这些优势是否有用,都无法嵌入。
old_timer

1

到目前为止,答案是关于CPU可以发挥作用的“速度”以及DMA如何从中受益。但是,还有另一个考虑因素,即功率

如果CPU希望在慢速链接上发送数据包,则在使用轮询或中断的情况下,大部分时间都需要保持唤醒状态,但是在完成DMA时,主CPU可能处于睡眠状态。


0

诸如STM32H7系列之类的某些处理器具有很多RAM选项和大量紧密耦合的RAM。拥有独立的RAM组可以使DMA锤击大量RAM,而处理器则在不需要缓存且不受DMA锤击的紧密耦合内存中处理数据。要移动数据,可以使用MDMA。我使用其中之一建造了FMCW雷达装置。ADC从两个输入端获取IQ数据到一个SRAM中。然后,我缩放数据并在dtcm ram中执行浮点256 bin复数fft。然后使用MDMA将结果FIFO放入AXI ram中的2d数组中。

我在fifo上取第二个fft 64 bin作为速度矢量。然后,我处理复杂数据的大小,并使用12.5 MHz的SPI将结果数据128和64浮点值发送到另一个H7,以进行检测。我在4毫秒内完成了所有这些操作。

ADC的采样率为84 kHz,使用过采样后,我的分辨率约为18位。

对于仅在MHz范围内运行且没有外部RAM的通用处理器来说还不错。

此外,该设备的大型缓存还改善了dtcm之外的计算性能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.