9. DMA
9.1 介绍
Direct memory access(DMA) 直接存储器访问。
这两个DMA控制器总共有16个流(每个控制器8个),每个流用于管理来自一个或多个外围设备的内存访问请求。每个流总共可以有8个通道(请求)。每个都有一个仲裁器来处理DMA请求之间的优先级。
9.2 特点
DMA的主要特性是:
- 双AHB主总线架构,一个专用于内存访问,一个专用于内存访问专用于外围访问
- AHB slave programming 接口只支持32位访问
- 每个DMA控制器有8个流,每个流最多有8个通道(请求)
- 每个流的4字节深度的32位先入先出内存缓冲区(FIFOs)用于FIFO模式或直接模式
FIFO模式:软件可选1/4,1/2或3/4之间的FIFO大小
- 直接模式: 每个DMA请求立即启动一个from/to内存的传输。当它被配置为直接模式(FIFO被禁用),在内存向外设模式下传输数据时,DMA仅将一个数据从内存预加载到内部FIFO,以确保在外设触发DMA请求时立即进行数据传输。
- 每个流可以由硬件配置为:
- 支持外设到内存,内存到外设,内存到内存的常规通道
- 在内存端也支持双缓冲的双缓冲通道
- 这8个流中的每一个都连接到专用的硬件DMA通道(请求)
- DMA流请求之间的优先级是软件可编程的(4级:非常高,高,中,低),请求0优先级高于请求1,以此类推
- 每个流还支持软件触发当用于内存到内存的传输传输时(只有DMA2控制器支持)
- 每个流请求可以在多达8个可能的通道请求中进行选择。这选择是软件可配置的,并允许多个外设初始化DMA请求
- 要传输的数据的数量可以由DMA控制器或外设控制
- DMA流控制器:要传输的数据项的数量是软件可编程的从1到65535
- 外设流控制器:要传输的数据项的数量是未知的,并受控于在传输结束时源或目标外设通过硬件的发出结束信号的控制。
- 独立的源和目标传输宽度(字节、半字、字):源和目标的数据宽度不相等,DMA自动打包/解包必要的传输以优化带宽。此功能仅在FIFO模式下可用。
- 对于源和目标的递增或非递增寻址
- 支持4、8或16拍的递增突发传输。爆发的大小可由软件配置,通常等于外设FIFO大小的一半
- 每个流都支持循环缓冲区管理
- 每一个流都有5种事件标志(DMA传输一半,DMA传输完成,DMA传输错误,DMA FIFO错误,直接模式错误)以逻辑或的形式组合在一个中断请求中
9.3 DMA功能介绍
9.3.1 一般说明


9.3.2 DMA事务
DMA事务由给定数量的数据传输序列组成。要传输的数据项的数量和它们的宽度(8位、16位或32位)是软件可编程的。
每次DMA传输都包含三个操作:
- 加载。从外设数据寄存器或内存中的某个位置进行的加载,通过DMA_SxPAR或DMA_SxM0AR寄存器进行寻址
- 存储。加载到外设数据寄存器或内存中的某个位置的数据的存储,通过DMA_SxPAR或DMA_SxM0AR寄存器寻址
- 自减。DMA_SxNDTR寄存器自减,其中包含仍然需要执行的事务
DMA事务完成后,外设向DMA控制器发送请求信号。DMA控制器根据通道优先级为请求提供服务。只要DMA控制器访问外设,DMA控制器就会发送给外设一个确认信号。外设一旦收到来自DMA控制器的确认信号就会释放它的请求。一旦请求被外设取消,DMA控制器释放应答信号。如果有更多的请求,则外设可以启动下一个事务。
9.3.3 通道选择
每个流都与一个DMA请求相关联,可以从8个可能的DMA请求中选择一个通道请求。选择由DMA_SxCR中的CHSEL[2:0]位控制。

来自外设的8个请求(TIM、ADC、SPI、I2C等)是独立连接的每个通道。
DMA请求映射的示例见下表。


9.3.4 仲裁
仲裁程序根据8个DMA流请求各自的优先级管理它们AHB主端口(内存和外设端口)并启动外设/内存访问序列。
优先级管理分为两个阶段:
- 软件:每个流的优先级可以在DMA_SxCR寄存器中配置。有四个级别:
- 非常高的优先级
- 高优先级
- 中优先级
- 低优先级
- 硬件:如果两个请求具有相同的软件优先级,则流具有较低的数字优先于具有较高数字的流。例如,流2优先于流4。
9.3.5 DMA 流
每个DMA流可配置为:
- 常规类型事务:内存到外围设备、外围到内存或内存到内存传输
- 双缓冲区类型事务:使用两个内存指针进行双缓冲区传输内存(当DMA读写一个缓冲区时,应用程序可以读写另一个缓冲区)。
要传输的数据量(最多为65535)是可编程的,并与连接到外围AHB端口的请求DMA传输的外围设备的源宽度有关。包含要传输的数据项数量的寄存器在每个事务完成之后递减。
9.3.6 源、目的和传输模式
源和目标传输都可以处理整个外围设备和内存4gb区域,地址从0x0000 0000到0xFFFF FFFF。
该方向使用DMA_SxCR寄存器中的DIR[1:0]位配置并提供三种可能:内存到外设、外围到内存或内存到内存的传输。表24描述了相应的源地址和目标地址:

当数据宽度(以DMA_SxCR寄存器中的PSIZE或MSIZE位进行编程)是半字或一个字时,写入DMA_SxPAR或DMA_SxM0AR/M1AR寄存器中外设地址或内存地址也必须半字或一个字对齐地址边界。
Peripheral-to-memory mode
图24描述了这种模式。
当启用此模式时(通过在DMA_SxCR寄存器中设置位EN),每次一个外设请求发生时,流会启动一个从源的传输以填充FIFO。
当FIFO达到阈值水平时,FIFO的内容被排干并存储到目标中。
当外设请求传输结束(在外设流控制器的情况下)或当DMA_SxCR寄存器的EN位被软件清除时,DMA_SxNDTR寄存器为0,传输停止。
在直接模式下(当DMA_SxFCR寄存器中的DMDIS值为' 0 '时),阈值FIFO级别不可用:每次从外围设备到FIFO的数据传输完成后,相应的数据立即排干并存储到目的地。
只有当流赢得仲裁时,该流才能访问AHB源或目的端口。此仲裁按照DMA_SxCR寄存器中的PL[1:0]位为每个流定义的优先级执行。

Memory-to-peripheral mode
图25描述了这种模式。
当启用此模式时(通过在DMA_SxCR寄存器中设置EN位),流立即启动从源的传输到完全填充FIFO。
每次发生外围设备请求时,FIFO的内容都会被提取并存储到其中的目的地。
当FIFO的级别低于或等于预定义的阈值级别,FIFO将被内存中的数据重新加载满。
当外设请求传输结束(在外设流控制器的情况下)或当DMA_SxCR寄存器的EN位被软件清除时,DMA_SxNDTR寄存器为0,传输停止。
在直接模式下(当DMA_SxFCR寄存器中的DMDIS值为'0'时),阈值没有使用先进先出级别。一旦流被启用,DMA预加载第一个数据到转移到内部FIFO。
在直接模式下(当DMA_SxFCR寄存器中的DMDIS值为' 0 '时),阈值FIFO级别不可用:每次从外围设备到FIFO的数据传输完成后,相应的数据立即排干并存储到目的地。
只有当流赢得仲裁时,该流才能访问AHB源或目的端口。此仲裁按照DMA_SxCR寄存器中的PL[1:0]位为每个流定义的优先级执行。
未完。
9. DMA的更多相关文章
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- z-stack协议uart分析(DMA)
1.从ZMain里面的main函数开始分析 2.进入int main( void ); HalDriverInit(); //硬件相关初始化,有DMA初始化和UART初始化 3.进入HalDriv ...
- STM32之DMA+ADC
借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...
- STM32F103之DMA
一.背景: 需要使用STM32的DAC,例程代码中用了DMA,对DMA之前没有实际操作过,也很早就想知道DMA到底是什么,因此,看了一下午手册,代码和网上的资料,便有了此篇文章,做个记录. 二.正文: ...
- ASM:《X86汇编语言-从实模式到保护模式》越计卷:实模式下对DMA和Sound Blaster声卡的控制
说实话越计卷作者用了16页(我还是删过的),来讲怎么控制声卡,其实真正归纳起来就那么几点. ★PART1:直接存储访问 1. 总线控制设备(bus master) 在硬件技术不发达的早期,处理器是最重 ...
- 【SPI】Polling Interrupt DMA
三種將資料在I/O間傳送的方法有 1. Polling2. Interrupt-driven I/O3. DMA(Direct Memory Access) Polling:最簡單的方式讓I/O de ...
- 关于DMA和它的仇家
[基础知识]什么叫做DMA?DMA=Direct Memory Access.这是一种通过硬件实现的数据传输机制.简单的说,就是不在CPU的参与下完成数据的传输.[/基础知识]不太明白?我举个简单的例 ...
- STM32——DMA接收和发送的实现
最近写程序,需要一段一段数据的接收,再通过其他串口发送出去. 老司机们建议用DMA通信,以节约CPU资源.然后,我听了,发现挺好用的.特此,把自己写的代码贴上了. DMA发送接收的步骤如下: 1.初始 ...
- include/asm/dma.h
/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $ * linux/include/asm/dma.h: Defines for using ...
- DMA控制器
DMA控制器依赖于平台硬件,这里只对i386的8237 DMA控制器做简单的说明,它有两个控制器,8个通道,具体说明如下: 控制器1: 通道0-3,字节操作, 端口为 00-1F 控制器2: 通道 4 ...
随机推荐
- java Wrapper包装类
什么是包装类?为什么需要包装类? 这是大家要了解的 对于java中的基本数据类型我们如果想要把当当做类来使用怎么办呢? 如果想要对这些基本数据类型直接调用一些方法来操作的话 怎么做呢? 由以上就产生了 ...
- Windows环境下Oracle数据库的自动备份脚本自动删除30天前的备份
@echo off echo ================================================ echo Windows环境下Oracle数据库的自动备份脚本 echo ...
- gradle打成jar包报错 "错误: 找不到或无法加载主类 App"(已经配置过主类)
文章目录 将gradle打成jar包(包括依赖) 运行jar包 报错 原因(src自己手动创建的) 解决(添加src目录) 将gradle打成jar包(包括依赖) jar { manifest { a ...
- ubuntu15.4、16.4、17.4设置nginx自启动
ubuntu15.4.16.4.17.4设置nginx自启动记录个小问题,备忘录.花了大半天的时间研究这个,网上大多ubuntu.centos的配置nginx开机自启的都是之前的 Upstart/Sy ...
- windbg bp condition
0:000> bp 0012f2fc "j @ecx == 0 '';'gc'" 0:000> g j代表judgement,与c++中的condition?A:B类似 ...
- python_面向对象,类名称空间,对象名称空间,组合
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两种属性:静态属性和动态属性 静态属性就是直接在类中定义的变量(字段) 动态属性就是定义在类中的方法 其中类 ...
- java入门之:Hello World
import java.util.Scanner; public class HelloWorld{ public static void main(String[] args){ //向终端打印he ...
- tomcat+nginx 单机部署多应用LINUX
1.首先虚拟机上安装nginx 和tomcat,这里安装就不赘述了. nginx安装可以参考https://www.linuxidc.com/Linux/2016-09/134907.htm,相关配置 ...
- Java中的session详解
一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...
- Linux入门命令
####常用的目录 /主目录 ① /root:存放启动Linux时启动的核心文件,包括一些连接文件以及镜像 ② /bin:binary的缩写,存放经常使用的命令 ③ /dev:Device(设备)的缩 ...