当前位置: 首页 > news >正文

【嵌入式原理系列-第七篇】DMA:从原理到配置全解析

目录

引言

一.源地址和目的地址

二.传输方向

三.外设位宽和存储器位宽

四.地址增量

五.传输计数

六.DMA和外设的处理通知

七.数据块传输和硬件FIFO

八.循环模式和普通模式

九.传输完成通知

十.DMA通道及优先级


引言

DMA(Direct Memory Access,直接存储器访问)是 MCU 中的重要外设,它的出现主要是为了提高数据拷贝的效率,通过一定的设计使得DMA可以代替CPU进行数据拷贝,从而将CPU从这种重复又耗时的工作中解放出来。


一.源地址和目的地址

DMA既然需要做数据拷贝,那么就需要指定源地址和目的地址,即从哪拷贝到哪。那么可以指定哪些目标?

可指定的目标分为两类:

  • 存储器:我们知道MCU的存储主要分为易失性存储器和非易失性存储器。DMA一般来说是无法对非易失性存储器进行操作的(用于存放数据的Data Flash由于只能按块读写,需要软件进行参与管理)。因此我们的目标也就是我们经常说的RAM(这里不区分SRAM和DRAM,统称RAM)。因此指定的存储器地址其实就是我们声明的全局变量的首地址。
  • 外设:这里指定的外设一般是通信类外设,比如UART。指定的外设地址实际上是外设提供的硬件缓冲区的地址,具体地址需要查询芯片手册。

二.传输方向

指定了源地址和目的地址后,我们还需要指定传输方向。即以下三选一(DMA不提供外设到外设的传输方向,一般来说这个选项没有实际意义):

  • 存储器(源)到外设(目的):使用较多,属于本文介绍的主要内容
  • 外设(源)到存储器(目的):使用较多,属于本文介绍的主要内容
  • 存储器(源)到存储器(目的):加速大数据块的拷贝传输(一般用的较少)

为什么指定了地址后还需要指定方向呢?DMA不能根据所指定的地址自行判断源和目的类型么?

我们需要知道MCU提供的地址有可能是虚拟地址,对于外设来说其缓冲区地址可能经过复杂的映射。并不像直接访问RAM那样方便。如果由用户随意指定地址交由DMA判断类型以及合法性,无疑会大大提供设计上的复杂度以及安全隐患。

通过简单的指定传输方向可以很大程度减少DMA设计复杂度,属于看起来冗余但是有用的设计。


三.外设位宽和存储器位宽

接下来我们需要配置外设位宽和存储器位宽。我们知道外设/CPU/存储器是通过总线来进行互通的,数据的通信效率收到总线位宽的限制。同时DMA的传输效率也收到源和目的地址能够处理的位宽最大值限制。

即我们每次DMA传输能发送的数据大小收到三个方面限制:

  • 源地址每次操作位宽
  • 目的地址每次接收位宽
  • 总线位宽

为了提高DMA的效率,一般源地址和目的地址位宽设置遵循以下规则:

  • 两者位宽一般设置相同值
  • 位宽满足MIN(源位宽,目的位宽,总线位宽):当用于外设和存储器之间通信时,一般实际都是受外设最大处理位宽限制。
  • 存储器设置优化:存储器的首地址和缓冲大小设置成4的倍数,这样可以减少拷贝过程中的对齐消耗。

四.地址增量

我们现在已经配置好了传输地址/传输方向/位宽。但是我们现在指定的地址是一个固定地址,假设传输方向是存储器到外设,位宽1字节,那么每次都是从固定地址取1字节,这样无疑非常低效。

因此,DMA提供了增量模式。即当设置后以上参数后,每次DMA传输会在位宽及相关参数的基础上偏移一个地址,这样就可以进行连续传输,比如将一个256字节的RAM数组从头到尾传输到UART外设。

存储器一般都需要配置为增量模式以提高传输效率,外设看具体芯片支持情况,大部分芯片的外设不支持外设地址增量(因为外设的缓冲区一般不大)。


五.传输计数

增量模式下,DMA并不知道你的缓冲区边界在哪里,因此需要显式指明传输计数。只要配置了增量模式,则必须配置传输计数,否则可能存在非法越界访问的风险。传输计数根据单次传输数据量以及缓冲区总大小计算。


六.DMA和外设的处理通知

刚才说过了DMA是按照位宽设置及相关参数来搬运数据,单次搬运数据量有限。对于存储器到存储器的搬运连续传输即可。

对于外设到存储器或者存储器到外设,由于外设需要一定的处理时间,因此需要有通知机制保证数据传输的正确性。即当外设收到数据或者数据处理完成需要通知DMA进行下一步的数据搬运。

这个外设和DMA之间的通知机制是依赖硬件来执行的,也是DMA的核心。如果没有这个硬件机制,则每一步的传输确认都需要软件执行,也就失去了DMA释放CPU工作量的初心。


七.数据块传输和硬件FIFO

前面介绍了外设每次处理完成需要通知DMA,DMA才能进行下一步的数据拷贝操作,为了提供效率(如果芯片支持)我们可以在中间设置一个硬件FIFO缓冲区,DMA每次拷贝若干个数据单元到FIFO缓冲区,外设按照FIFO次序顺序处理缓冲区的数据,这样可以减少DMA拷贝的次数。这个模式就叫做数据块传输。

需要注意的是,数据块传输必须配置DMA FIFO,否则无法生效,同时FIFO的深度需要大于数据块每次传输的最大数据量。


八.循环模式和普通模式

当按照传输计数和位宽传输完成了传输,理论上应该干什么?

当然是从头开始传输(循环模式)或者停止传输(普通模式)。DMA也提供了循环传输,当传输模式配置成循环+增量时,完成一轮传输后会从首地址重新进行传输。

循环模式下若CPU没来得及处理或者填充数据,重新开始传输会不会导致发送无效/重复数据(内存到外设)或者数据被覆盖(外设到内存)?

有可能出现此情况,因此在对安全性要求较高的汽车电子领域,一般采取以下做法。每次循环模式结束时,DMA会触发传输完成通知,CPU收到通知会立刻关闭循环模式,并根据传输方向进行数据填充或者数据处理,之后再打开循环模式。

既然如此为什么不直接配置普通模式,反正每次都是CPU关闭循环模式进行数据处理后再打开循环模式?

其实还是有意义的,因为循环模式下,许多参数不需要重新配置,如果是使用普通模式需要重新配置。此外循环模式对于一些对数据丢失不敏感的场景依然有很好的发挥。

车载领域适不适合使用双缓冲结构,即DMA往一个缓冲区写入/读取数据,CPU在另外一个缓冲区写入/读取数据?

安全性要求极高的车载领域,通常不推荐使用双缓冲结构。因为双缓冲机制要求CPU的处理速度必须始终高于DMA的数据吞吐速度,否则会导致缓冲区覆盖和数据丢失。这种依赖时序的假设在复杂的车载环境中难以得到绝对保证,因此引入了非确定性风险。更常见的做法是采用上述的‘半传输中断+循环模式’并结合安全机制(如看门狗、数据校验)来确保可靠性。


九.传输完成通知

DMA的传输完成通知一般使用中断形式,常用中断通知类型如下

传输完成中断:全部数据搬完后(由传输计数判断)再进行通知,一般用于传输方向内存到外设。若外设到内存使用此方法,当CPU处理数据时,新的数据可能会丢失,因此外设到内存一般建议使用半传输中断,此时不推荐使用传输完成中断。

半传输中断

即搬运到缓冲区一半时触发(由传输计数判断),主要用于传输方向为外设到内存时,传输一半就进行中断通知,之前CPU处理前一半数据,DMA继续搬运后一半数据。

传输方向为内存到外设时,使用此中断可以使数据处理处理时间曲线更平滑,减少数据堆积时间,不强制使用。

传输错误中断:外设未就绪、总线出错、非法地址等

注意!

当传输方向是外设到内存时,DMA中断场景覆盖有缺失,即当数据量达不到传输完成或者半传输完成的要求,但是又没有后续数据。这时候一般外设中断(不如UART的Idle中断)或者CPU轮询(不是主流)。


十.DMA通道及优先级

DMA控制器一般提供不止一个通道,每个通道可以选择一个源地址和目的地址,理论上各个通道是独立并行,但实际上一般的芯片设计不同DMA通道实际上是共用总线,因此需要设定不同通道之间的处理优先级。


想了解更多嵌入式技术知识,请点击阅读我的其他文章

烟花的文章链接集合-CSDN博客

如果你觉得内容对您有帮助,别忘了点赞、收藏和分享支持下哦


文章转载自:

http://o920NWR3.Ljcjc.cn
http://jApw87ew.Ljcjc.cn
http://VUXhkSAJ.Ljcjc.cn
http://izvB5HUr.Ljcjc.cn
http://yD9Inv0R.Ljcjc.cn
http://maZIs1jO.Ljcjc.cn
http://7yhwwiww.Ljcjc.cn
http://JAQF4xr7.Ljcjc.cn
http://1LI4kKPE.Ljcjc.cn
http://toVO0hsJ.Ljcjc.cn
http://cJiGFDx8.Ljcjc.cn
http://zVNEAxCT.Ljcjc.cn
http://kgvqkyqq.Ljcjc.cn
http://c8LFl8mo.Ljcjc.cn
http://jnrIratA.Ljcjc.cn
http://eLg2ChMl.Ljcjc.cn
http://P7EcsW5B.Ljcjc.cn
http://BklDQOdC.Ljcjc.cn
http://GHYVUvUH.Ljcjc.cn
http://v1Tk8XyB.Ljcjc.cn
http://VY7njAXQ.Ljcjc.cn
http://PSz9EPEt.Ljcjc.cn
http://UwgqKMWv.Ljcjc.cn
http://ErW0eKwF.Ljcjc.cn
http://e2ayFQJD.Ljcjc.cn
http://57OCVJbJ.Ljcjc.cn
http://gvArmnxx.Ljcjc.cn
http://EEQMzeNU.Ljcjc.cn
http://dEeKjcnS.Ljcjc.cn
http://Qm0y3ZlB.Ljcjc.cn
http://www.dtcms.com/a/375870.html

相关文章:

  • 最大异或对问题
  • Tess-two - Tess-two 文字识别(Tess-two 概述、Tess-two 文字识别、补充情况)
  • hot100 之移动零-283(双指针)
  • APP隐私合规评估测试核心要点与第三方APP检测全流程解析
  • ARM汇编与栈操作指南
  • 在 Keil 中将 STM32 工程下载到 RAM 进行调试运行
  • 高效数据操作:详解MySQL UPDATE中的CASE条件更新与性能优化
  • 构建企业级Selenium爬虫:基于隧道代理的IP管理架构
  • Nginx限流与防爬虫与安全配置方案
  • YOLO11训练自己数据集的注意事项、技巧
  • Kafka面试精讲 Day 13:故障检测与自动恢复
  • Linux学习——管理网络安全(二十一)
  • 平衡车 -- PID
  • 【ComfyUI】Flux Krea 微调完美真实照片生成
  • dp类相关问题(1):区间dp
  • TensorFlow 2.x 核心 API 与模型构建:从入门到实践
  • 华清远见25072班网络编程学习day2
  • 【论文写作】--网络与信息安全顶刊顶会
  • 【人工智能99问】如何基于QWen3进行LoRA微调?(38/99)
  • JAVA Predicate
  • 自动驾驶中的传感器技术41——Radar(2)
  • Netty HandlerContext 和 Pipeline
  • Stuns in Singapore!中新赛克盛大亮相ISS World Asia 2025
  • 开始 ComfyUI 的 AI 绘图之旅-LoRA(五)
  • 字符函数和字符串函数 last part
  • win安装多个mysql,免安装mysql
  • 开源项目_强化学习股票预测
  • Shell 脚本基础:从语法到实战全解析
  • Nginx如何部署HTTP/3
  • 解一元三次方程