【转载】基于Nios II的DMA传输总结(附源码)
转载:http://blog.ednchina.com/chactor/185802/message.aspx#92932
最近练了一段时间的DMA传输,现做如下的总结,分享自己获得心得以及遇到的一些问题。
在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令。
Nios II中的DMA传输有以下三种形式:
1、 存储器到存储器
这种情况下需要同时打开发送通道和接收通道,而且源地址和目标地址都是自增的。
tx = alt_dma_txchan_open("/dev/dma_0");//打开发送通道
dma_res = alt_dma_txchan_send(tx, tx_buf, 32, NULL, NULL); // tx_buf是源地址
rx = alt_dma_rxchan_open("/dev/dma_0");//打开接收通道
dma_res = alt_dma_rxchan_prepare(rx, rx_buf, 32, dma_done, NULL); // rx_buf是目标地址,dma_done()是DMA完成后被调用的回调函数。
2、 存储器到外设
这种情况下只要打开发送通道,而且源地址是自增的,目标地址是固定的。
tx = alt_dma_txchan_open("/dev/dma_0"); // 打开发送通道
alt_dma_txchan_ioctl(tx, ALT_DMA_TX_ONLY_ON, (void *)dst_addr); // dst_addr是目标地址
dma_res = alt_dma_txchan_send(tx, tx_buf, 32, dma_done, NULL); // tx_buf是源地址
3、 外设到存储器
这种情况下只要打开接收通道,而且源地址是固定的,目标地址是自增的。
rx = alt_dma_rxchan_open("/dev/dma_0"); // 打开接收通道
alt_dma_rxchan_ioctl(rx, ALT_DMA_RX_ONLY_ON, (void *)source_addr); // source_addr是源地址
dma_res = alt_dma_rxchan_prepare(rx, rx_buf, 32, dma_done, NULL); // rx_buf是目标地址
其中通过alt_dma_txchan_ioctl,alt_dma_rxchan_ioctl还可以设置每次发送和接收的字节数。
下面给出两个实例,说明DMA传输的过程。
1、 存储器到存储器
下面程序为SDRAM到onchip-memory的数据传输。
硬件连接图示:
程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/alt_dma.h>
#include "system.h"
static volatile int rx_done = 0;
int rc;
alt_dma_txchan txchan;
alt_dma_rxchan rxchan;
static char buff[256];
void* tx_data = (void*) buff; /* 源地址 */
void* rx_buffer = (void*) 0x01801000; /* 目标地址,从上图看到0x01801000为onchip-memory的地址*/
//DMA传输结束回调函数
static void done_t(void* handle, void* data)
{
rx_done++;
}
int main (int argc, char* argv[], char* envp[])
{
/* 打开发送通道 */
if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL)
{
printf ("Failed to open transmit channel\n");
exit (1);
}
/* 打开接收通道 */
if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL)
{
printf ("Failed to open receive channel\n");
exit (1);
}
/* 开始发送数据 */
if ((rc = alt_dma_txchan_send (txchan,
tx_data,
128,
NULL,
NULL)) < 0)
{
printf ("Failed to post transmit request, reason = %i\n", rc);
exit (1);
}
/* 开始接收数据*/
if ((rc = alt_dma_rxchan_prepare (rxchan,
rx_buffer,
128,
done_t,
NULL)) < 0)
{
printf ("Failed to post read request, reason = %i\n", rc);
exit (1);
}
/* 等待传输结束 */
while (!rx_done);
printf ("Transfer successful!\n");
return 0;
}
程序运行结束后在Nios IDE的console界面中显示:
Transfer successful!
表明传输成功。
2、 存储器到UART
下面程序为SDRAM到UART的数据传输
硬件连接图:
程序如下:
#include <stdio.h>
#include <stdlib.h>
#include "sys/alt_dma.h"
#include "altera_avalon_uart_regs.h"
#include "system.h"
#include "alt_types.h"
static volatile int tx_done = 0;
volatile static alt_u8 chr[20] = {1,2,3,4,6,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20} ;//待发送的数据
//回调函数
static void done (void* handle)
{
tx_done++;
}
int main()
{
int rc;
alt_dma_txchan txchan;
void* source_buff_ptr = (void*) chr; /* 源地址 */
void* destination_buff_ptr = (void*)IOADDR_ALTERA_AVALON_UART_TXDATA(UART_BASE); /* 目标地址IOADDR_ALTERA_AVALON_UART_TXDATA(UART_BASE)函数读出txdata的地址 */
/* 打开发送通道 */
if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL)
{
printf ("Failed to open transmit channel\n");
exit (1);
}
/* 设置目标地址固定 */
if ((rc = alt_dma_txchan_ioctl(txchan, ALT_DMA_TX_ONLY_ON, destination_buff_ptr)) < 0)
{
printf ("Failed to set ioctl, reason = %i\n", rc);
exit (1);
}
//设置每次发送一个字节,即8位,因为UART每次只发送8位
if((rc = alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_8 ,NULL))<0)
{
printf("Failed to set mode 8\n");
exit(1);
}
/* 开始发送 */
if ((rc = alt_dma_txchan_send(txchan, source_buff_ptr, 20, done, NULL)) < 0)
{
printf ("Failed to post transmit request, reason = %i\n", rc);
exit (1);
}
/* 等待发送结束 */
while (!tx_done);
printf ("Transfer successful!\n");
return 0;
}
不过该程序执行结束后,在串口调试器中显示Transfer successful!,却没有显示DMA发送的那20个数字。不知道哪里需要修改,放在这里和大家讨论下。
转载于:https://www.cnblogs.com/kongtiao/archive/2011/09/23/2185783.html
【转载】基于Nios II的DMA传输总结(附源码)相关推荐
- 基于FPGA数字时钟的设计(附源码)
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注"FPGA技术江湖"微信公众号,在"闯荡江湖"."行侠仗义"栏里获取其 ...
- java计算机毕业设计ssm基于SSM学生信息管理系统37myx(附源码、数据库)
java计算机毕业设计ssm基于SSM学生信息管理系统37myx(附源码.数据库) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm ...
- 基于SSM实现的人力资源管理系统【附源码】(毕设)
一.项目简介 本项目是一套基于SSM实现的人力资源管理系统 或 人事管理系统 或 企业管理系统 或 HR管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 详细介绍 ...
- 基于SSM实现的物流管理系统【附源码】(毕设)
一.项目简介 本项目是一套基于SSM实现的物流管理系统 或 物流配送系统 或 快递物流系统 或 快递管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 详细介绍了物 ...
- 基于C++开发的仓库管理系统(附源码)
基于C++开发的仓库管理系统(附源码) 一.简介 1.开始菜单 2.登录后的菜单 二.C++代码 main.cpp 一.简介 仓库管理系统的功能有登录.注册.查询功能.入库功能.出库功能.添加 ...
- 高分毕设基于JAVA的仓库管理系统项目(内附源码)
一.高分毕设基于JAVA的仓库管理系统项目(内附源码) 项目简介:(源码免费下载链接如下) 基于JAVA的仓库管理系统项目源码.zip-Java文档类资源-CSDN下载 在经过多家公司上线运行后,为了 ...
- 基于 SpringBoot + Vue 的物流管理系统(附源码)
国庆期间哪也没去,在家闲来无事,写了一个基于 SpringBoot + Vue 的物流管理系统,把源码分享给大家,在文章结尾处,自行获取即可~ 一.介绍 基于Java的物流管理系统. 二.软件架构 系 ...
- 基于jsp+servlet+mysql的酒店管理系统(附源码)
本系统是基于jsp+servlet+mysql的前后端分离的酒店管理系统,前后端分离是指前端和后端分别是两个独立存在的项目,能独立运行.没有前端项目,后端也能运行且进行数据管理,没有后端项目,前端也能 ...
- h5 数字变化_基于JS实现数字动态变化显示效果附源码
先给大家展示下效果,感觉不错,可以参考实现代码,文末附有源码哦. 1.目标 以液晶电子表样式,动态变化的在指定元素内显示数字. 目标关键词:动态变化(定时器),指定元素(DOM元素ID),数字(num ...
最新文章
- R语言效用分析 ( 效能分析、Power analysis)、除了pwr包之外还有其它包、例如、基因研究中的效能分析、MBESS包可用于各种形式的效能分析和最少样本量确定、其他效用分析包的简要介绍
- supervisor守护进程的安装配置使用
- application.properties中自定义属性的使用
- leetcode刷题集:栈与队列
- 如何设计日志系统_架构 - 如何设计一个百亿级日志系统
- Redis学习笔记三:Redis的数据类型
- RAC Debug开关修改工具
- 使用srvany.exe把程序安装成windows服务的方法
- [原创]一篇无关技术的小日记(仅作暂存)
- 研究生课程笔记:软件包在流行病学中的应用(二)——csurvey软件+抽样调查
- 开发谷歌浏览器翻译插件
- 将US7ASCII 字符集的数据转到ZHS16GBK 字符集数据库
- 入门教程pythonpython完整教程视频
- HDU 4069 Squiggly Sudoku DLX
- python根据文本生成词云图
- 弹窗广告关不掉?工信部:用这个方法举报!
- 微信支付商户API 证书的用途及生成API安全证书的方法(仅退款、撤销订单时需要)
- VR行业中的三维扫描技术应用
- VisualFreeBasic:VisualBasic6望尘莫及之变量
- DNS与CDN知识汇总(前端优化一)