我们这里主要以STM32平台为例进行说明。
一、DMA到底能不能起到加速的作用 初学的时候,很容易存在这样的认识,DMA直接从一个外设到另一个外设的数据传输,少了CPU的参与,直接硬件传输,应该可以做到更快。 我们这里用实验数据说话,争取有理有据,下面是STM32H7的DMA2D,DMA1,DMA2,MDMA和CPU复制粘贴的性能测试: 1、可以看到DMA1/DMA2的性能跟其它不是一个级别的,适合搞搞低速的外设。 2、DMA2D,MDMA和CPU复制粘贴的性能差不多。 3、CPU操作ITCM的数据粘贴性能最强的。
那么DMA到底能不能起到加速的作用?
1、如果相比CPU的复制粘贴来说,基本没什么加速作用。
2、如果从程序执行效果来看,可以起到明显加速效果,特别是MDMA和DMA2D,因为DMA刷新期间,CPU可以腾出手来干别的事情,这个才是DMA做的最大作用。
3、另外像DMA2D做它的本职工作,比如颜色格式转换等操作,有明显加速作用,这个比CPU要快。还有像H7的SDMMC带的IDMA和以太网带的DMA,这些是外设专属DMA,不需要CPU参与,从程序的执行效果上也能起到加速作用。
2、DMA死等操作是否合理 这个问题也谈的非常多,这里从DMA的两个方向讨论: 1、一类是直接在DMA中断里面处理消息,像H7自带的ADC,DAC,串口等。 这类应用我们可以直接在中断里面处理消息或者搞个双缓冲。 这种应用在RTOS下和裸机下使用都比较简单,这类应用不需要死等。 裸机下: 适合直接在中断里面处理,搞个外置标志效果不是很理想,不方便性能最大化。 RTOS下: 可以中断里面处理,也可以发送信号量等消息,通知任务里面处理,性能可以最大化。 2、还有一类就是图形加速DMA2D,QSPI Flash DMA,SDIO DMA等 这类DMA应用,我们一般都需要配合GUI,FAT文件系统等一起使用。 这种情况下,要分裸机和RTOS两种做分析,这类应用使用死等(可以加超时溢出)比较方便。 裸机情况下: 如果不做死等,而做个中断,做个变量标识什么的做等待,应用层代码基本没有办法写了,比如一个简单的GUI桌面背景部分重绘,需要进入DMA2D加速接口函数等待中断标志完成,应用层代码实现非常麻烦。 RTOS下: 这种情况下,在RTOS下里才能发挥威力,以GUI为例,我们都是直接将其丢到最低优先级任务里面跑。文件系统类的QSPI Flash,SD卡,eMMC,NAND等,也可以直接丢到低优先级任务,或者其他稍高优先级任务,完全不影响其他高优先级任务运行。 其实这也是使用RTOS相比裸机的一个重要优势。
3、多个DMA数据流同时刷是否处理过来: 先来看下通用DMA框图 : F1系列
F4系列
H7系列
基本上都是一个多路选择器(优先级仲裁)选通那一路外设使用DMA,即同一个DMA,同一时刻只能处理1个DMA请求。 尽管如此,DMA的带宽处理多个简单的外设像DAC, ADC, 串口,I2C,SPI之类的还是无压力的,通用DMA1, DMA2的性能基本在60-70MB/S,同时处理8路串口DMA不定长收发还是无压力的。 但是一些时间控制类的应用很容易爆DMA性能极限,比如DAC1, DAC2,ADC1,ADC2,ADC3都开DMA,都开定时器触发,如果触发速度开的太高,很容易出现采集的波形异常,或者停止工作的问题。 这种情况,可以考虑分配DMA1和DMA2都开启,分别处理一些DMA请求。