西安官方网站建设,photoshop免费下载,网站开发模板系统,wordpress 页面编辑器文章目录 前言一、DMA是什么#xff1f;二、K210的DMA实验过程总结 前言
本章我们来介绍K210的DMA控制器#xff0c;大家应该都知道在大数据量传输时#xff0c;如果CPU全程参与#xff0c;是非常浪费资源的#xff0c;于是芯片内置了DMAC用做传输控制#xff0c;CPU仅仅… 文章目录 前言一、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 .. -DPROJdma -G MinGW Makefiles
make编译完成后在build文件夹下会生成dma.bin文件。
使用type-C数据线连接电脑与K210开发板打开kflash选择对应的设备再将程序固件烧录到K210开发板上。 实验现象如下 总结
DMAC是可以提高CPU效率直接通过DMA在设备和内存之间传输数据而CPU只需要启动dma传输就可以等待完成即可直接内存存取控制器DMAC需要搭配其他的设备如串口、I2C或者I2S通讯来使用发送和传输使用不同的通道