AI嵌入式K210项目(9)-DMA

文章目录

  • 前言
  • 一、DMA是什么?
  • 二、K210的DMA
  • 实验过程
  • 总结


前言

本章我们来介绍K210的DMA控制器,大家应该都知道在大数据量传输时,如果CPU全程参与,是非常浪费资源的,于是芯片内置了DMAC用做传输控制,CPU仅仅在输出传输开始和结束时参与,这样大大降低了CPU的负载,同时也可以加快传输的速率,一举两得,本章我们一起来学习下;


一、DMA是什么?

MA 传输将数据从一个地址空间复制到另外一个地址空间。当CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。

在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。一个完整的DMA传输过程必须经过DMA请求、DMA响应、DMA传输、DMA结束4个步骤。

请求:CPU对DMA控制器初始化,并向I/O接口发出操作命令,I/O接口提出DMA请求。

响应:DMA控制器对DMA请求判别优先级及屏蔽,向总线裁决逻辑提出总线请求。当CPU执行完当前总线周期即可释放总线控制权。此时,总线裁决逻辑输出总线应答,表示DMA已经响应,通过DMA控制器通知I/O接口开始DMA传输。

传输:DMA控制器获得总线控制权后,CPU即刻挂起或只执行内部操作,由DMA控制器输出读写命令,直接控制RAM与I/O接口进行DMA传输。

在DMA控制器的控制下,在存储器和外部设备之间直接进行数据传送,在传送过程中不需要中央处理器的参与。开始时需提供要传送的数据的起始位置和数据长度。

结束:当完成规定的成批数据传送后,DMA控制器即释放总线控制权,并向I/O接口发出结束信号。当I/O接口收到结束信号后,一方面停止I/O设备的工作,另一方面向CPU提出中断请求,使CPU从不介入的状态解脱,并执行一段检查本次DMA传输操作正确性的代码。最后,带着本次操作结果及状态继续执行原来的程序。

由此可见,DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,使CPU的效率大为提高。

辅助大家理解的话,也可以参考我的这篇博客 STM32开发(16)----CubeMX配置DMA

二、K210的DMA

直接存储访问 (Direct Memory Access, DMA) 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据,从而提高了 CPU 的效率。

DMA 模块具有以下功能:
• 自动选择一路空闲的 DMA 通道用于传输
• 根据源地址和目标地址自动选择软件或硬件握手协议
• 支持 1、2、4、8 字节的元素大小,源和目标大小不必一致
• 异步或同步传输功能
• 循环传输功能,常用于刷新屏幕或音频录放等场景

DMAC 具有高度可配置化,高度可编程,在总线模式下传输数据具有高效率,DMAC 控制器具有多主机,
多频道等特点。DMAC 具有如下特点:
多达八个通道,每路通道都有源和目的地对
每个通道数据传输数据时每个时刻只能有一个方向传输,不同通道则不受影响
• 内存-内存,内存-外设,外设-内存,外设-外设的 DMA 传输
• 具有独立的核心,主接口和从接口独立时钟
• 当所有外设不活动时主接口可以关闭其时钟来省电
• 输入管脚可以动态选择大小端制式
• 通道锁支持,支持内部通道仲裁,根据数据传输的优先级来使用主接口总线的特权
• DMAC 状态输出,空闲/忙指示
• DMA 传输分配成传输中,被中断,传输完成等传输等级

对应的头文件 dmac.h
为用户提供以下接口
• dmac_init
• dmac_set_single_mode
• dmac_is_done
• dmac_wait_done
• dmac_set_irq
• dmac_set_src_dest_length
• dmac_is_idle
• dmac_wait_idle

实验过程

DMA支持的使用方式非常多,如内存-内存,内存-外设,外设-内存,外设-外设的 DMA 传输,我们这个实验做一个从外设->内存读取数据,然后将数据再使用DMA将数据从内存->外设传输出去;
新建dma文件夹,在其中新建main.c文件
在这里插入图片描述
本示例使用UART3外设,代码实现如下,其实和之前的UART实验很类似,只是在发送和接收的时候使用了uart_receive_data_dma() , uart_send_data_dma()这两个API,其实各种外设基本都支持DMA,可以到对应外设的API部分去查找使用,这里注意的是,发送和接收使用了两根不同的DMA通道,不要重复了
代码实现如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "uart.h"
#include "sysctl.h"
#include "fpioa.h"// 硬件IO口,与原理图对应
#define PIN_UART_USB_RX       (4)
#define PIN_UART_USB_TX       (5)/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define UART_USB_NUM           UART_DEVICE_3/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_UART_USB_RX       (FUNC_UART1_RX + UART_USB_NUM * 2)
#define FUNC_UART_USB_TX       (FUNC_UART1_TX + UART_USB_NUM * 2)/**
* Function       hardware_init
* @brief         硬件初始化,绑定GPIO口
* @param[in]     void
* @param[out]    void
* @retval        void
* @par History   无
*/
void hardware_init(void)
{// fpioa映射fpioa_set_function(PIN_UART_USB_RX, FUNC_UART_USB_RX);fpioa_set_function(PIN_UART_USB_TX, FUNC_UART_USB_TX);
}/**
* Function       main
* @brief         主函数,程序的入口
* @param[in]     void
* @param[out]    void
* @retval        0
* @par History   无
*/
int main(void)
{hardware_init();// 初始化串口3,设置波特率为115200uart_init(UART_USB_NUM);uart_configure(UART_USB_NUM, 115200, UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE);char *hello = {"hello world!\n"};uart_send_data_dma(UART_USB_NUM, DMAC_CHANNEL0, (uint8_t *)hello, strlen(hello));uint8_t recv = 0;while (1){/* 通过DMA通道1接收串口数据,保存到recv中 */uart_receive_data_dma(UART_USB_NUM, DMAC_CHANNEL1, &recv, 1);/* 通过DMA通道0发送数据到串口 */uart_send_data_dma(UART_USB_NUM, DMAC_CHANNEL0, &recv, 1);}return 0;
}

代码写好后,我们开始编译,注意:如果你编译过程中出现错误,可以先make clean掉之前生成的过程文件,重新生成

cd build
//注意这里的目标文件目录改成dma,和刚才新建的文件夹名称一致
cmake .. -DPROJ=dma  -G "MinGW Makefiles"
make

编译完成后,在build文件夹下会生成dma.bin文件。

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。
在这里插入图片描述
实验现象如下:
在这里插入图片描述


总结

DMAC是可以提高CPU效率,直接通过DMA在设备和内存之间传输数据,而CPU只需要启动dma传输就可以,等待完成即可,直接内存存取控制器DMAC需要搭配其他的设备,如串口、I2C或者I2S通讯来使用,发送和传输使用不同的通道;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue面试之v-if与v-show的区别

Vue面试之v-if与v-show的区别 DOM渲染初始渲染性能切换开销标签配合源码实现 最近在整理一些前端面试中经常被问到的问题&#xff0c;分为vue相关、react相关、js相关、react相关等等专题&#xff0c;可持续关注后续内容&#xff0c;会不断进行整理~ 作为Vue中两种条件性渲染元…

C#,入门教程(17)——条件语句(if-else)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(16)——可变数据类型&#xff08;var&#xff09;的基础知识与使用禁忌https://blog.csdn.net/beijinghorn/article/details/124032216 程序的核心是逻辑。 逻辑的核心是布尔条件表达式。 逻辑的主要体现形式之一是 if-else 语句…

上位机编程:ASCII码精讲

一 ASCII码介绍&#xff1a; ASCII&#xff08;American Standard Code for Information Interchange&#xff09;码是一种使用数字来表示字符的编码标准。它是一种字符编码&#xff0c;将常见的字符映射到数字&#xff0c;以便计算机能够理解和处理文本数据。 ASCII码最初是为…

十大排序算法模板

☆* o(≧▽≦)o *☆嗨~我是小奥&#x1f379; &#x1f4c4;&#x1f4c4;&#x1f4c4;个人博客&#xff1a;小奥的博客 &#x1f4c4;&#x1f4c4;&#x1f4c4;CSDN&#xff1a;个人CSDN &#x1f4d9;&#x1f4d9;&#x1f4d9;Github&#xff1a;传送门 &#x1f4c5;&a…

本地一键部署grafana+prometheus

本地k8s集群内一键部署grafanaprometheus 说明&#xff1a; 此一键部署grafanaPrometheus已包含&#xff1a; victoria-metrics 存储prometheus-servergrafanaprometheus-kube-state-metricsprometheus-node-exporterblackbox-exporter grafana内已导入基础的dashboard【7个…

户外火光如何玩转?智能酒精壁炉安全使用攻略大揭秘!

在户外使用智能酒精壁炉是一个别致而令人惬意的选择&#xff0c;但在享受户外炉火带来的温馨时&#xff0c;也需要注意一些安全和使用细节。下面将介绍智能酒精壁炉在户外使用需要注意的事项。 智能酒精壁炉需放置在平坦、通风的户外场地&#xff0c;远离易燃物体&#xff0c;确…

Maven 搭建私服

一、Maven 私服简介 1.1 私服简介 Maven 私服是一种特殊的 Maven 远程仓库&#xff0c;它是架设在局域网内的仓库服务&#xff0c;用来代理位于外部的远程仓库&#xff08;中央仓库、其他远程公共仓库&#xff09;。 当然也并不是说私服只能建立在局域网&#xff0c;也有很多公…

网络部署实战具体学习内容总结

网络部署实战具体学习内容总结 &#x1f4bb;网络部署实战课程通常旨在教授学生如何规划、配置、维护和优化计算机网络。这些课程涵盖了广泛的主题&#xff0c;以确保学生具备网络部署和管理所需的技能。 网络部署实战课程具体学习内容&#x1f447; 1️⃣网络架构设计及网络原…

第一个Python程序_获取网页 HTML 信息[Python爬虫学习笔记]

使用 Python 内置的 urllib 库获取网页的 html 信息。注意&#xff0c;urllib 库属于 Python 的标准库模块&#xff0c;无须单独安装&#xff0c;它是 Python 爬虫的常用模块。 获取网页 HTML 信息 1) 获取响应对象 向百度&#xff08;http://www.baidu.com/&#xff09;发起…

九州金榜|孩子厌学是家庭教育原因还是学校教育原因?

孩子厌学&#xff0c;这是一个让所有家长的头疼的问题&#xff0c;尤其在看到别人家孩子是学霸的时候&#xff0c;就更会有种莫名其妙的伤感&#xff0c;然后回想自己的孩子&#xff0c;仿佛全都是缺点&#xff0c;家长要是有这种想法那就大错特错了&#xff0c;其实每个孩子都…

杨中科 .NETCORE EFCORE第七部分 一对一,多对多

一对一 一对一关系配置 1、builder.HasOne(o >o.Delivery).WithOne(d>d.Order).HasForeignKey(d>dOrderId); 2、测试插入和获取数据 示例 新建 Order 新建 Delivery DeliveryConfig OrderConfig 执行 迁移命令 查看数据库 测试数据插入 运行查看数据 多对多…

【Shell编程练习】编写 shell 脚本,打印 9*9 乘法表

系列文章目录 输出Hello World 通过位置变量创建 Linux 系统账户及密码 监控内存和磁盘容量&#xff0c;小于给定值时报警 猜大小 输入三个数并进行升序排序 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态 系列文章目录编写 shell 脚本,打…

软件测试|如何使用selenium处理下拉框?

简介 下拉框是网页表单中常见的元素之一&#xff0c;通常用于选择不同的选项。对于我们的自动化测试工作来说&#xff0c;操作下拉框是我们经常需要处理的元素&#xff0c;selenium作为我们最常使用的web自动化测试框架&#xff0c;也是支持我们对下拉框进行操作的。本文我们就…

【问题+解决】axios/vue/element/echarts引入报错

缘由 笔者在html页面引用vue来快速实现页面&#xff1b;<head></head>中通过<script>src""></script>方法引入&#xff0c;开始引入&#xff0c;应用都是正常&#xff0c;后来用了也没问题&#xff1b;奇怪的是&#xff0c;前几天发现htm…

代码随想录算法训练营第6天 | 242.有效的字母异位词 , 349. 两个数组的交集 , 202. 快乐数 , 1. 两数之和

哈希知识基础 文章链接&#xff1a;https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%93%88%E5%B8%8C%E8%A1%A8 242.有效的字母异位词 题目链接&#xff1a;https://leetcode.cn/problems/valid-anagram/description/…

Qt根据单价计算总价与进制转换

1.相关说明 二进制、十进制、十六进制间的相互转换 2.界面绘制 3.相关主要代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete …

路由黑洞和黑洞路由的区别

路由黑洞&#xff1a; 路由黑洞是一种现象&#xff0c;一般是在网络边界做汇总回程路由的时候产生的一种不太愿意出现的现象&#xff0c;就是汇总的时候有时会有一些不在内网中存在的网段&#xff0c;但是又包含在汇总后的网段中&#xff0c;如果在这个汇总的边界设备上同时还配…

【SQL】SQL语法小结

相关资料 参考链接1&#xff1a;SQL 语法&#xff08;超级详细&#xff09; 参考链接2&#xff1a;史上超强最常用SQL语句大全 SQL练习网站&#xff1a;CSDN、牛客、LeetCode、LintCode SQL相关视频&#xff1a; 推荐书籍&#xff1a; 文章目录 数据分析对SQL的要求SQL语法简介…

Android Traceview 定位卡顿问题

Traceview 是一个 Android 性能分析工具&#xff0c;用于时间性能分析&#xff0c;主要帮助开发者了解应用程序中各个方法的执行时间和调用关系。通过图形化界面查看应用程序的代码执行细节&#xff0c;包括每个方法的调用次数、方法调用的时间消耗、方法调用堆栈等信息。我们可…

Java、C#、Python间的Battle

一、编译原理和开发效率 编译速度&#xff1a; C# &#xff08;约大于等于&#xff09; JAVA > Python python的编译原理 前提&#xff1a;python 3.6 python不会直接编译源码 而是把源码直接扔给解释器&#xff0c;这种方式 使得python非常灵活&#xff0c;让它的开发效…