什么是DMA
DMA,Direct Memory Access,直接内存访问,是一种不经过CPU而直接从内存存取数据的数据交换模式。在DMA模式下,CPU只需要向DMA控制器下达指令,传输数据由DMA来完成,数据传送完再把信息反馈给CPU,这样能够减少CPU的资源占有率。DMA由硬件实现,从共用系统数据总线的角度看,DMA和CPU是竞争对手的关系,当完成一批数据的传输工作之后,快速设备可以向CPU发出中断请求,报告本次传输结束的同时,请示下一步的操作要求。
应用场合
DMA应用于快速设备和主存储器成批交换数据的场合,DMA应用在数据交换,既能够保证数据传输的准确性,即不丢失快速设备提供出来的数据,也能够进一步减少快速设备读写操作对CPU的干扰。
DMA中断和普通中断的区别
两者最大的不同表现为对CPU的干扰程度不同:DMA 传送方式的优先级高于程序中断,两者的区别主要表现在对CPU的干扰程度不同。中断请求不但使CPU停下来,而且要CPU执行中断服务程序为中断请求服务,这个请求包括了对断点和现场的处理以及CPU与外设的传送,所以CPU付出了很多的代价;DMA请求仅仅使CPU暂停一下,不需要对断点和现场的处理,并且是由DMA控制外设与主存之间的数据传送,无需CPU的干预,DMA只是借用了一点CPU的时间而已。还有一个区别就是,CPU对这两个请求的响应时间不同,对中断请求一般都在执行完一条指令的时钟周期末尾响应,而对DMA的请求,由于考虑它的高效性,CPU在每条指令执行的各个阶段之中都可以让给DMA使用,是立即响应。 DMA主要由硬件来实现,此时高速外设和内存之间进行数据交换不通过CPU的控制,而是利用系统总线。DMA方式是I/O系统与主机交换数据的主要方式之一,另外还有程序查询方式和中断方式。
DMA特性
● 12个 独立的可配置的通道(请求)DMA1 有7个通道, DMA2有5个通道
● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。
● 在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如在相等优先权时由硬件决定(请求0优先于请求1 ,依此类推) 。
● 独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。
● 支持循环的缓冲器管理
● 每个通道都有3个事件标志(DMA 半传输, DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。
● 存储器和存储器间的传输
● 外设和存储器,存储器和外设的传输
● 闪存、 SRAM、外设的SRAM、 APB1 APB2和AHB外设均可作为访问的源和目标。
● 可编程的数据传输数目:最大为65536
DMA配置过程
(1)外设寄存器地址;DMA_CPARx(x=1-7),DMA1和DMA2共享用7个,DMA2没有6和7
(2)存储器地址;DMA_CMARx(x=1-7),DMA1和DMA2共享用7个99,DMA2没有6和7
(3)传输量,DMA_CNDTRx,只用bit0-15,0-65535,只在DMA_CCRx的EN为0时,可写,减为0时,不会发生任何数据传输,除非使用循环模式;传输数据宽度,传输方向,DMA_CCRx
(4)循环/正常模式,地址增量模式(包括外设和存储器的地址),DMA_CCRx
(5)通道优先级,DMA_CCRx
(6)中断请求标志,DMA_ISR和DMA_IFCR
DMA的工作过程及循环模式、存储器到存储器模式
配置DMA完后,并且使能了DMA,当发生外设数据传输请求时,如果传输量不为0,在DMA的控制下,数据以指定的方向,以传输数据宽度,从源地址传输到目标地址,一次传输完成,传输量减1,此时如果开启了地址增量模式,那么下一个源地址、目标地址将会是前一个地址加上增量值,增量值取决于所选的数据宽度(8位+1,16位+2,32位+4),当源地址设定的数据宽度小于目标地址的数据宽度,那么源数据全部写入目标地址后,目标地址剩下的位置将写0,当大于时,目标地址将全被写满,源数据未写部分将被舍弃。如果开启了循环模式,数据传输量变为0时,将会自动恢复成配置通道时设置的初值,DMA操作继续执行。
如果开启了中断(传输错误中断、传输完成中断、半传输中断),将会产生相应的中断事件。三种不同中断共用一个中断函数,但可以通过中断标志区分。
当设置了DMA_CCRx的MEM2MEM位,在软件设置了DMA_CCRx的EN位启动DMA传输,DMA传输立即开始,当传输量减为0,传输结束。注意存储器到存储器模式不能和循环模式共同使用。
DMA的DMA_ISR和DMA_IFCR的区别
DMA_ISR,存储中断标志位,由硬件置位,使用了前28位,共7个通道,每个通道使用4位,分别是GIFx(全局中断)、TCIFx(传输完成)、HTIFx(半传输)、TEIFx;特别地,GIFx 置1时,表示有中断发生。
DMA_IFCR,中断标志清除寄存器,由软件置位, 使用了前28位,共7个通道,每个通道使用4位,分别是CGIFx(全局中断)、CTCIFx(传输完成)、CHTIFx(半传输)、CTEIFx;写入0不起作用,写入1清除DMA_ISR相应的标志位。
错误管理
读写一个保留的地址区域,将会产生DMA传输错误。当在DMA读写操作时发生DMA传输错误时,硬件会自动地清除发生错误的通道所对应的通道配置寄存器(DMA_CCRx)的EN位,该通道操作被停止。此时,在DMA_IFT寄存器中对应该通道的传输错误中断标志位(TEIF)将被置位,如果在DMA_CCRx寄存器中设置了传输错误中断允许位,则将产生中断。
操作一个不支持字节或半字写的AHB设备
当DMA模块开始一个AHB的字节或半字写操作时,数据将在HWDATA[31:0]总线中未使用的部分重复。因此,如果DMA以字节或半字写入不支持字节或半字写操作的AHB设备时(即HSIZE不适于该模块),不会发生错误, DMA将按照下面两个例子写入32位HWDATA数据:
● 当HSIZE=半字时,写入半字’0xABCD’, DMA将设置HWDATA总线为’0xABCDABCD’。
● 当HSIZE=字节时,写入字节’0xAB’, DMA将设置HWDATA总线为’0xABABABAB’。
假定AHB/APB桥是一个AHB的32位从设备,它不处理HSIZE参数,它将按照下述方式把任何AHB上的字节或半字按32位传送到APB上:
● 一个AHB上对地址0x0(或0x1 、 0x2或0x3)的写字节数据’0xB0’操作,将转换到APB上对地址0x0的写字据’0xB0B0B0B0’操作。
● 一个AHB上对地址0x0(或0x2)的写半字数据’0xB1B0’操作,将转换到APB上对地址0x0的写字数据’0xB1B0B1B0’操作。
例如,如果要写入APB后备寄存器(与32位地址对齐的16位寄存器),需要配置存储器数据源宽度(MSIZE)为’16位’,外设目标数据宽度(PSIZE)为’32位’。
注意:
(1)存储器到存储器模式下,可以使用任意DMA通道;
(2)开启DMA数据传输模式,除了存储器到存储器的数据传输,其他外设的DMA传输,不仅要支持DMA,还要在使用的时候,自己开启DMA功能,比如USART1的DMA开启为,USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
(3)外设的DMA,还要注意选择的通道是否正确。

- STM32的SPI口的DMA读写[原创www.cnblogs.com/helesheng]
SPI是我最常用的接口之一,连接管脚仅为4根:在常见的芯片间通信方式中,速度远优于UART.I2C等其他接口.STM32的SPI口的同步时钟最快可到PCLK的二分之一,单个字节或字的通信时间都在us以 ...
- 【分享】【原创开源应用第4期】给ili9488,RA8875类显示屏的emWin底层增加DMA加速方案
说明:1.emWin底层中最重要的一个优化就是16bpp绘制,特此为其增加DMA加速,已经支持RA8875和ili9488.2.使用中务必将emWin任务设置为除了空闲任务,统计任务以外的最低优先级, ...
- 1--STM32 ADC1与ADC2 16通道DMA采集笔记(原创)
最近在搞ADC,网上还是很多资源的,以下为参考链接:1.对STM32 ADC单次转换模式 连续转换模式 扫描模式的理解:https://www.cnblogs.com/zhanghankui/p/51 ...
- 存储器结构、cache、DMA架构分析--【原创】
存储器的层次结构 高速缓冲存储器 cache 读cache操作 cache如果包含数据就直接从cache中读出来,因为cache速度要比内存快 如果没有包含的话,就从内存中找 ...
- 内存映射MMAP和DMA【转】
转自:http://blog.csdn.net/zhoudengqing/article/details/41654293 版权声明:本文为博主原创文章,未经博主允许不得转载. 这一章介绍Linux内 ...
- DMA为什么比轮询、中断方式性能要卓越非常多?(你不懂)
本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/35735397 假设是计算机专业出身的同学,都听过一个 ...
- Linux硬盘的检测(原创)
http://czmmiao.iteye.com/blog/1058215 概述 随着硬盘容量.速度的快速发展,硬盘的可靠性问题越来越重要,今天的单块硬盘存储容量可轻松达到1TB,硬盘损坏带来的影响非 ...
- 为树莓派添加一个强实时性前端[原创cnblogs.com/helesheng]
树莓派是最近流行嵌入式平台,其自由的开源特性以及低廉的价格,吸引了来 自全球的大量极客和计算机大咖的关注.来自各大树莓派社区的幕后英雄,无私地在这个开源硬件平台上做了大量的工作,将其打造成了世界上通用 ...
- S3C6410 SPI全双工读写流程分析(原创)【转】
转自:http://blog.csdn.net/hustyangju/article/details/21165721 原创博文,知识共享!转载请注明出处:http://blog.csdn.net/h ...
随机推荐
- 在windows下golang安装zmq3小记
备忘这个 安装 TDM-GCChttp://tdm-gcc.tdragon.net/download 设置环境变量set C_INCLUDE_PATH=d:\DevTools\Zmq\ZeroMQ 3 ...
- log4j日志的使用
1.引架包和导配置文件log4j.properties <dependency> <groupId>org.slf4j</groupId> <artifact ...
- Adnroid开发环境搭建(四步搞定)
新手博友,多多关照 下面给大家介绍JDK Eclipse AndroidSDK ADT环境搭建,安装教程 第一步.安装JDK: 第二步.安装Eclipse: 第三步.下载并安装AndroidSDK: ...
- Java中的一个类型转换问题
一.Object转Integer Java中hibernate或者ResultSetHandler查询sql语句, 返回的object类型其实是Long类型, 而不是Integer类型, 因此此时直接 ...
- OC中重写set和get方法、懒加载
在写OC程序的时候,在很多时候我们会用到重写set或者get方法,重写这两个方法大多是用于刷新数据,比如懒加载. 意思就是说当你去调用set或者get方法时,系统会去调用重写的get或者set方法,这 ...
- Djangoの1
有ip无路由是404,ip也无是无法访问此网站.url中?前的是路由,?后是GET请求的各组参数. 子项目和子应用下的两类urls.py:[]内的各个路由函数url,其首参网址的开头无/,结尾有/ ...
- ARM指令学习
跳转指令 直接向程序计数器PC写入i跳转地址值,可以实现在4GB的地址空间中的任意跳转. ARM跳转指令可以完成向前或向后的32MB的地址空间的跳转. -B 跳转指令 -BL 带返回的跳转指令 -BL ...
- Android-MySQLiteOpenHelper的理解
MySQLiteOpenHelper: package com.esandinfo; import android.content.Context; import android.database.s ...
- php安全编程&python测试实例编写
前言 本文首发i春秋论坛. 本篇文章主要分享一个python暴破脚本,该脚本采用optparse模块,支持自定义字典位置:用了多线程(虽然我感觉和单线程速度差不多..是我的错觉还是线程写的不对..求表 ...
- 脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
本文引用了公众号纯洁的微笑作者奎哥的技术文章,感谢原作者的分享. 1.前言 老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天.实时音视频等)时,如果发现网络连接超时,第一时间想到的就是 ...