我最近正在使用mbed(LPC1768)做一个项目,使用DAC输出各种波形。我阅读了数据表的各个部分,并讨论了许多外设如何使用DMA。这似乎很有用,但是在进一步阅读后,我发现DMA使用的数据总线与cpu相同(我认为这是正常的)。这是否意味着在DAC获取数据时CPU无法与任何存储器交互?另外,由于DAC没有缓冲区(据我所知),因此必须经常进行DMA,DMA的意义何在?如果CPU无法执行内存事务,它可以做什么?
我最近正在使用mbed(LPC1768)做一个项目,使用DAC输出各种波形。我阅读了数据表的各个部分,并讨论了许多外设如何使用DMA。这似乎很有用,但是在进一步阅读后,我发现DMA使用的数据总线与cpu相同(我认为这是正常的)。这是否意味着在DAC获取数据时CPU无法与任何存储器交互?另外,由于DAC没有缓冲区(据我所知),因此必须经常进行DMA,DMA的意义何在?如果CPU无法执行内存事务,它可以做什么?
Answers:
我发现的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使CPU能够以其本机速度有效运行,而外设可以以其本机速度有效运行。该示例中的大多数数字都是虚构的。
让我们比较两个选项以定期从ADC收集数据:
让我们将1000个样本从ADC传输到RAM。
使用选项1:每个样本都有
假设这个中断功能是76条指令,假设单周期执行(最佳情况),整个例程长100条指令。这意味着选项1将花费100,000个CPU时间周期执行。
选项2:将DMA配置为收集1000个ADC样本。假设ADC具有来自计时器计数器的硬件触发。
假装整个中断(带有进入和退出开销)是100个单周期指令。使用DMA,您只需花费100个周期即可保存相同的1000个样本。
现在,每次DMA访问总线时,是的,CPU和DMA之间可能会发生争执。甚至可能迫使CPU等待DMA完成。但是,等待DMA完成要比将CPU锁定来维修ADC短得多。如果CPU核心时钟为2x总线时钟,则CPU可能会浪费几个核心周期来等待DMA完成。这意味着您的传输有效执行时间在1000个周期(假设CPU从不等待)到9000个周期之间。仍然比100,000个周期更好。
如果在给定的周期上处理器和DMA控制器需要访问同一条总线,则一个或另一个将必须等待。但是,许多系统包含具有独立总线的多个内存区域以及一个总线“桥”,该桥将允许CPU访问一个存储器,而DMA控制器访问另一个存储器。
此外,许多CPU可能不需要在每个周期访问存储设备。如果CPU通常只需要在三个周期中的两个周期内访问内存,则低优先级DMA设备可能能够利用内存总线空闲时的周期。
即使在每个DMA周期都会导致CPU停顿一个周期的情况下,但是,如果数据到达的速度足够慢,以至于CPU应该能够在传入的数据项之间执行其他操作,则DMA可能仍然非常有用。 ,但速度足够快,因此需要将每个项目的开销降至最低。例如,如果SPI端口以每16个CPU周期以1字节的速率向设备馈送数据,则为每次传输中断CPU可能会导致它花费几乎全部时间进入和退出中断服务程序,而没有中断做任何实际的工作。但是,使用DMA,即使每次DMA传输导致CPU停顿两个周期,开销也可以减少到13%。
最后,某些CPU允许在CPU处于睡眠状态时执行DMA。使用基于中断的传输将要求系统为每个传输的数据单元完全唤醒。但是,使用DMA时,睡眠控制器有可能在每次输入一个字节时向存储控制器提供几个时钟,但让其他所有对象保持睡眠状态,从而降低了功耗。
作为程序员,DMA是向与支持它的外围设备之间传输数据的一种选择。对于通过串行外围设备(如SPI或UART)移动大型缓冲区或从ADC收集大量样本的经典示例,您可以通过以下三种方法移动数据:
轮询方法。在这里等待寄存器标志,以允许您移入/移出下一个字节。问题是您在等待CPU的同时阻止了CPU的所有执行。或者,如果您必须在操作系统中共享CPU时间,则传输将大大减慢。
中断方法。在这里,您编写一个中断服务程序(ISR),该程序在每次字节传输时都执行,并在ISR中编写代码以管理传输。这会提高CPU效率,因为CPU仅在需要时才会为您的ISR提供服务。除ISR以外,其他所有时间均可免费使用。从传输速度来看,ISR也是进行传输的较快选择之一。
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上。
DMA最有可能在这里使用,因此DAC可以具有一些常规定时,可以通过以某个已知间隔更改模拟输出来生成波形。
是的,如果这是共享巴士,那么...您必须共享。
CPU并不总是使用总线,因此与DMA引擎共享有时是个好主意。当然,这意味着优先级会涉及到,有时只是先到达优先级(例如,在资源前面有一个命令fifo,然后按照请求到达的顺序对请求进行fifo,是的,这不一定是确定性的)。在这种情况下,您可能希望dma优先于cpu,以便对时间敏感的事物(如DAC或ADC)具有确定的时序。取决于他们选择如何实施。
人们有时会错误地认为dma是免费的。它是否仍会消耗总线时间,如果与cpu共享(它最终是在与cpu可以与之交谈的资源进行通讯时),则cpu和/或dma会被推迟,因此cpu仍然必须等待一些时间。有时,在某些实现中(可能不是您的微控制器),CPU会完全推迟,直到DMA完成为止,而CPU会持续一段时间。只是取决于实现。它的自由之处在于,不必为了某些事件而持续不断地中断CPU或轮询或屏住呼吸来馈送数据。创建dma的下一个缓冲区可能要花费一些时间。它确实必须注意dma传输是否完成并进行处理,但是现在不必说每个字节而是多个字节,而是一些数据块。
没有一个普遍的答案。“取决于” ...取决于您所使用的特定物品的特定设计。即使在一个芯片/板/系统设计中,也可能有多个dma引擎,没有理由假定它们都以相同的方式工作。对于每个实例,您都必须弄清楚,但是不幸的是,他们经常没有记录或记录得足够好。因此,如果您担心的话,可能必须创建一些实验。
诸如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之外的计算性能。