打印

请问,如何高效的使用单片机的DMA?

[复制链接]
5734|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
年轻不在|  楼主 | 2010-3-28 20:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我对DMA的理解是:
它用于把CPU从忙等待的数据传输中解脱出来,使得CPU可以利用数据传输的时间来执行其他操作。

使用DMA以前,代码也许是这样:

for(i = 0; i < 512; ++i){
    while(数据没有准备好);    // 等待
    *buff++ = 数据源[i];
}
处理buff中的数据;

在把数据传输到buff这个过程中,cpu在忙等待,或者即便没有等待也要由cpu来完成把数据源拷贝到buff这个任务。
但是,如果使用DMA来传输数据就可以节约下这些CPU时间。

使用DMA的代码也许是这样:

设置DMA传输的数据源地址;
设置DMA传输的数据目标地址;
设置传输数据的数目;
启动DMA传输;
等待DMA传输完毕;               // ??我的疑问在这里
处理数据;


如果用while循环来等待DMA传输完毕,那么CPU时间仍然浪费了。正确的做法应该是DMA传输的过程中,CPU去做其他的事情。如果有操作系统,可能这里就是一个阻塞自己的系统调用,操作系统进行任务的切换做其他的事情去了,等到DMA完成再由操作系统把自己给唤醒。另外一方面,如果没有其他事情需要做,用不用DMA都是没有关系的。对吗?

这样来看,是不是说要发挥DMA的价值,就得给单片机移植一个操作系统,进行任务的管理?

谢谢了。

相关帖子

沙发
想实习去| | 2010-3-28 20:59 | 只看该作者
用简单的超级循环+中断也可以。配置好参数后启动DMA,进入DMA中断服务程序后设置某个全局标志。主循环每一圈都要检查这个标志,这种作法跟普通的中断没有区别

使用特权

评论回复
板凳
QQAI| | 2010-3-28 21:00 | 只看该作者
这样呢?
设置DMA传输的数据源地址;
设置DMA传输的数据目标地址;
设置传输数据的数目;
启动DMA传输;
while(1){

    if(等待DMA传输完毕)              
    {   
         重新配置DMA参数;
         处理数据;            
    }
     
    其他任务

}

如果是实现一个文件系统的读写库函数,还是想不太出来怎么归结到这个模式中来。

使用特权

评论回复
地板
yoyowodeai| | 2010-3-28 21:01 | 只看该作者
你认为传输中必须CPU等待,所以感觉CPU没有解放。RTOS中有好的方法可以实现“等待”,不带OS也可以用状态机等方法,总之不会让CPU等待而不干别的事。你上边那种方式就是最简单的等待了。

使用特权

评论回复
5
3B1105| | 2010-3-28 21:01 | 只看该作者
可以使用 DMA传输完毕 中断,进中断了后再处理你的数据

使用特权

评论回复
6
huzixian| | 2010-3-28 21:02 | 只看该作者
如果要实现一个SD卡上的文件系统。函数调用关系可能是:

f_read  --->   disk_read   --->    spi_read_write

disk_read通常是调用512次spi_read_write来一个sd卡上的扇区,如果512bytes数据还没有读取完毕,disk_read不应该返回,
如果改用dma通过读取数据,disk_read中设置好dma参数,启动dma传输后,能返回吗?
如果返回,dma还没有读取完数据,如果不返回,改为等待dma传输完毕,这和cpu自己做这件事相比又有什么区别呢?性能并没有得到提高啊。

采用dma传输完毕中断通知?怎么做,想不出来。

使用特权

评论回复
7
金鱼木鱼| | 2010-3-28 21:03 | 只看该作者
"如果用while循环来等待DMA传输完毕,那么CPU时间仍然浪费了。正确的做法应该是DMA传输的过程中,CPU去做其他的事情。如果有操作系统,可能这里就是一个阻塞自己的系统调用,操作系统进行任务的切换做其他的事情去了,等到DMA完成再由操作系统把自己给唤醒。另外一方面,如果没有其他事情需要做,用不用DMA都是没有关系的。对吗?  

这样来看,是不是说要发挥DMA的价值,就得给单片机移植一个操作系统,进行任务的管理?  

谢谢了。 "



DMA在传输的时候要占用总线,所以CPU是不能动的.CPU不是在死循环等待,而是完全当机中,直到传完.之所以要用DMA,不是因为DMA不占CPU,而是因为DMA的传输比通过CPU中转要快几十倍上百倍---不然PC里要几GB的总线带宽来干什么?
DMA只在传大块的数据时有才优势,在一般的小单片机系统里用DMA,几乎没有意义.

使用特权

评论回复
8
maoyanketi| | 2010-3-28 21:04 | 只看该作者
不同同意楼上“DMA在传输的时候要占用总线,所以CPU是不能动的.CPU不是在死循环等待,而是完全当机中,直到传完,之所以要用DMA,不是因为DMA不占CPU,而是因为DMA的传输比通过CPU中转要快几十倍上百倍---不然PC里要几GB的总线带宽来干什么?”这个观点。

首先,一个缓慢的外设并不是总是占用总线的,而且是几乎不占用总线。简单算一下,STM32中以18MHz最快速度进行SPI操作,一个字节需要至少8个时钟,就是大约450ns一个字节,用DMA来传输只需要每450ns占用一次总线,stm32以72MHz速度工作,一个时钟周期是14ns,450ns里已经有30个时钟周期了。

第二,在cortex-m3内核中,指令总线,数据总线,外设总线是独立的,我理解DMA操作和CPU取值操作是可以并行的。

第三,PC里几GB的总线是快过DMA的,也就是用CPU直接IO比DMA快,所以DMA在这个意义上存在的价值是应该讨论的。

使用特权

评论回复
9
年轻不在|  楼主 | 2010-3-28 21:05 | 只看该作者
每个DMA通道的速度不一样。
不过对 AVR32 SPI/UART的相对低速模块的DMA模块功能,应该是每收发1byte数据时短时占用一下内存总线,CPU暂停一下后还是继续运行,直到DMA完成整个数据包后,产生中断.

DMA等效于一个产生完成中断信号的低速外部模块。

使用特权

评论回复
10
六楼的窗户| | 2010-3-28 21:05 | 只看该作者
看晕了
其实你可以把DMA看成是一个功能单一的CPU(传输数据),所以它不会占用cpu资源,而是占用总线资源.
基本原理是,dma传输时,会向cpu申请总线,如果有空,得到总线开始传输,这时cpu不一定是啥都不干的,它可以译码,执行等等,当它需要使用总线时只好等待上次dma完成(这时cpu才是挂着的)
那么dma传输对cpu到底有多大影响呢,这个要看dma的模式了
一般我们用的都是,dma每个读写周期完(就是每传输完一个字节/半字/字),cpu都有机会得到总线,所以这种情况下,dma会使cpu慢一点,慢多少很难说,一般不大.这就显示了dma的优点,充分利用总线资源
还有一种dma模式,它会在整个传输过程中占用总线,这种模式下,cpu是挂着的(我猜突发传输是不是这种模式,哪位高手解答下)
还有一种称为on_the_fly的dma模式,它在传输数据时只需要一个周期就能完成读和写,这个明显比cpu快了一倍

使用特权

评论回复
11
xinzha| | 2010-3-28 21:06 | 只看该作者
DMA结束的时候会给出一个中断,当你配置好DMA之后就可以把cpu拿走干别的去了。
打个比方说,假如你的系统是一个做视频软解码的系统,当你把一帧数据解出来之后,你就可以把这个视频数据的buffer首地址交给dma控制器,目的地址可以是你输出的任意一种类型地址,启动dma之后,释放cpu继续做下一帧视频的解码,当dma传输完成之后给出中断,cpu回收dma通道和内存等资源,然后继续解码。
需要注意的是,此时要注意总线问题,如果总线配置得不好的话,dma传输的时候,cpu一样得空转。

使用特权

评论回复
12
z_no1| | 2010-3-29 08:42 | 只看该作者
还有一种情况:
普通的非DMA的从一个数据发送完毕到第2个数据送进寄存器,中间是要处理的,有间隔,而DMA/FIFO就不会有这个间隔,这样总线的实际速度就大大增加了,

使用特权

评论回复
13
lagogo2012| | 2012-9-15 08:39 | 只看该作者
直接设置寄存器

使用特权

评论回复
14
summerlover| | 2012-9-16 21:23 | 只看该作者
楼上说的简直跟没说有啥区别

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

106

主题

447

帖子

1

粉丝