搜索
bottom↓
回复: 16

请问,如何高效的使用单片机的DMA?【恢复】

[复制链接]

出0入0汤圆

发表于 2008-9-25 22:45:28 | 显示全部楼层 |阅读模式
我对DMA的理解是:

它用于把CPU从忙等待的数据传输中解脱出来,使得CPU可以利用数据传输的时间来执行其他操作。



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



for(i = 0; i < 512; ++i){

    while(数据没有准备好);    // 等待

    *buff++ = 数据源

}

处理buff中的数据;



在把数据传输到buff这个过程中,cpu在忙等待,或者即便没有等待也要由cpu来完成把数据源拷贝到buff这个任务。

但是,如果使用DMA来传输数据就可以节约下这些CPU时间。



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



设置DMA传输的数据源地址;

设置DMA传输的数据目标地址;

设置传输数据的数目;

启动DMA传输;

等待DMA传输完毕;               // ??我的疑问在这里

处理数据;





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



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



谢谢了。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2008-10-7 18:13:54 | 显示全部楼层
【12楼】 ifree64 

积分:541

派别:

等级:------

来自:

 谢谢rainyss 



但是,如果我说错了希望你能给我指正,比如我把什么原理性的东西给混淆了。 

我是觉得你说错了,而且我说出了我的论据。 







你说的那个是分级总线.老式PC用的是单一总线,DMA传输时,整个DMA传输周期完成前CPU是不能工作的,因为总线被DMA锁住,CPU不能取指.现代PC结构改进了一些,采用了分级,但在一般的小系统里用分级总线不现实.





至于不同意我的观点也无所谓,你去用就好了,别光磨嘴皮子,嘴上争赢了又有什么用呢?动手才是硬道理.

出0入0汤圆

发表于 2008-9-29 17:21:27 | 显示全部楼层
七楼:

DMA在传输的时候要占用总线,所以CPU是不能动的.CPU不是在死循环等待,而是完全当机中,直到传完.之所以要用DMA,不是因为DMA不占CPU,而是因为DMA的传输比通过CPU中转要快几十倍上百倍---不然PC里要几GB的总线带宽来干什么? 

DMA只在传大块的数据时有才优势,在一般的小单片机系统里用DMA,几乎没有意义. 



不敢苟同



1.M3使用的总线机制使DMA的数据传送(使用AHB)和cpu的取指(使用I-CODE)可以并发操作!



2.大部分时间DMA是进行外设传送(APB to AHB)。也就是说在一个DMA周期内AHB总会有一个空闲周期提供给cpu访问AHB。



3.在极端情况下。即使用DMA和CPU同时进行内存复制。cpu将因为得不到APB响应而挂起。



11楼:

唉...8楼的...倒不是我要否认你的话,但有些原理性的东西不要混淆的好.建议重新看看计算机原理的书吧.至于DMA运作的同时CPU还可以工作,书上也有解释的. 



re:书上的永远都是落后的知识!建议看看 版主bluelucky 的新书!收获会很大!

出0入22汤圆

发表于 2008-9-28 17:08:38 | 显示全部楼层
谢谢。

出0入0汤圆

发表于 2008-9-28 17:05:24 | 显示全部楼层
看晕了

其实你可以把DMA看成是一个功能单一的CPU(传输数据),所以它不会占用cpu资源,而是占用总线资源.

基本原理是,dma传输时,会向cpu申请总线,如果有空,得到总线开始传输,这时cpu不一定是啥都不干的,它可以译码,执行等等,当它需要使用总线时只好等待上次dma完成(这时cpu才是挂着的)

那么dma传输对cpu到底有多大影响呢,这个要看dma的模式了

一般我们用的都是,dma每个读写周期完(就是每传输完一个字节/半字/字),cpu都有机会得到总线,所以这种情况下,dma会使cpu慢一点,慢多少很难说,一般不大.这就显示了dma的优点,充分利用总线资源

还有一种dma模式,它会在整个传输过程中占用总线,这种模式下,cpu是挂着的(我猜突发传输是不是这种模式,哪位高手解答下)

还有一种称为on_the_fly的dma模式,它在传输数据时只需要一个周期就能完成读和写,这个明显比cpu快了一倍

出0入0汤圆

 楼主| 发表于 2008-9-27 18:47:54 | 显示全部楼层
谢谢rainyss



但是,如果我说错了希望你能给我指正,比如我把什么原理性的东西给混淆了。

我是觉得你说错了,而且我说出了我的论据。

出0入0汤圆

发表于 2008-9-27 17:47:50 | 显示全部楼层
唉...8楼的...倒不是我要否认你的话,但有些原理性的东西不要混淆的好.建议重新看看计算机原理的书吧.至于DMA运作的同时CPU还可以工作,书上也有解释的.

出0入0汤圆

发表于 2008-9-27 16:40:08 | 显示全部楼层
有了这个疑问,LZ学习“嵌入式实时操作系统”(UCOS-II之类)就会比其它人理解的更深入一层了。
头像被屏蔽

出0入0汤圆

发表于 2008-9-27 16:09:42 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2008-9-27 16:06:34 | 显示全部楼层
不同同意楼上“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在这个意义上存在的价值是应该讨论的。

出0入0汤圆

发表于 2008-9-27 14:38:24 | 显示全部楼层
TO楼主:

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



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



谢谢了。 "







DMA在传输的时候要占用总线,所以CPU是不能动的.CPU不是在死循环等待,而是完全当机中,直到传完.之所以要用DMA,不是因为DMA不占CPU,而是因为DMA的传输比通过CPU中转要快几十倍上百倍---不然PC里要几GB的总线带宽来干什么?

DMA只在传大块的数据时有才优势,在一般的小单片机系统里用DMA,几乎没有意义.
头像被屏蔽

出0入0汤圆

发表于 2008-9-27 14:21:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2008-9-27 14:05:43 | 显示全部楼层
如果要实现一个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传输完毕中断通知?怎么做,想不出来。

出0入0汤圆

发表于 2008-9-26 19:27:55 | 显示全部楼层
可以使用 DMA传输完毕 中断,进中断了后再处理你的数据

出0入0汤圆

发表于 2008-9-26 17:49:49 | 显示全部楼层
你认为传输中必须CPU等待,所以感觉CPU没有解放。RTOS中有好的方法可以实现“等待”,不带OS也可以用状态机等方法,总之不会让CPU等待而不干别的事。你上边那种方式就是最简单的等待了。

出0入0汤圆

 楼主| 发表于 2008-9-26 08:11:08 | 显示全部楼层
谢谢bluelucky,像这样吗



设置DMA传输的数据源地址;

设置DMA传输的数据目标地址;

设置传输数据的数目;

启动DMA传输;

while(1){



    if(等待DMA传输完毕)             

    {  

         重新配置DMA参数;

         处理数据;            

    }

    

    其他任务



}



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

出0入0汤圆

发表于 2008-9-26 07:16:54 | 显示全部楼层
用简单的超级循环+中断也可以。配置好参数后启动DMA,进入DMA中断服务程序后设置某个全局标志。主循环每一圈都要检查这个标志,这种作法跟普通的中断没有区别
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-17 03:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表