DMA传输小结_dma传输方式

2020-02-27 其他工作总结 下载本文

DMA传输小结由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“dma传输方式”。

关于DMA传输的几点说明:memory 到 外设的传输,调用alt_dma_txchan_ioctl()时,有一个参数为alt_dma_tx_only_on等 2调用alt_dma_txchan_send函数时,在传输结束前就返回一个值,如果此值为负的话,说明发送请求失败。正确传输结束后,调用done函数。接收函数alt_dma_rxthan_prepare类似上面的1和2 4传输结束,有两种可能:数据传完或者end of packet(要预先使能)Sopc builder中例化时要制定哪些可以访问DMA的主端口,DMA的avalon slave端口要接cpu。实际传输的最大数可以帮助确定设置的位数alt_dma_txchan_ioctl用于控制dma的一些工作性质,使用多的话可以用信号量等来“抢占” 7dma传输最小应该传4字或者其倍数。

两图是地址为什么加4的原因(每个寄存器32位,偏移为1时,地址应该加4)

内存到串口的DMA传输程序!

(使用的是HAL API函数,用IOWR灯访问reg调整参数也可以)

#include “system.h” #include #include #include “altera_avalon_pio_regs.h” #include “altera_avalon_uart_regs.h” #include “altera_avalon_timer_regs.h” #include “altera_avalon_dma_regs.h”

#include “alt_types.h” #include “sys/alt_irq.h” #include “sys/alt_dma.h”

static volatile int rx_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};//发送字符volatile static char *chr =“asdfghjkloiuytrewqzx”;

static void done(void* handle, void* data)//DMA传输结束调用函数 { rx_done++;} main(){ int rc,cwg;alt_dma_txchan txchan;

if((txchan = alt_dma_txchan_open(“/dev/dma”))== NULL){ printf(“Failed to open transmit channeln”);exit(1);}

cwg = alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_8 ,NULL);cwg = alt_dma_txchan_ioctl(txchan,ALT_DMA_TX_ONLY_OFF,NULL);// cwg = alt_dma_txchan_ioctl(txchan,ALT_DMA_RX_ONLY_OFF,NULL);cwg = alt_dma_txchan_ioctl(txchan,ALT_DMA_TX_ONLY_ON,UART1_BASE + 4);// ALT_DMA_TX_ONLY_ON代表使用流模式,UART1_BASE + 4是要写的地址(寄存器偏移为1时,+4)if((rc = alt_dma_txchan_send(txchan, chr , 20, done, NULL))

/* Wait for transfer to complete */

while(!rx_done);printf(“%d”,rx_done);rx_done = 0;}

程序二,memory to memory的程序如下:

在NIOS II的HAL DMA设备模式中,DMA传输被分为两类:transmit 和 receive。NIOS提供两种设备驱动实现transmit channels和receive channels,transmit channels把缓冲区数据发送到目标设备,receive channels读取设备数据存放到缓冲区。

为了适应大家不同的开发环境,下面我们完成一个相对简单的DMA操作,复制SDRAM内存缓冲区到on_chip_memory中,如果我们在库工程属性中设置了SDRAM为主内存,那么程序中分配的数组缓冲区就在SDRAM中,我们用指针赋值让指针指向on_chip_memory。这个操作完全可以在程序中用memcpy来实现,我们趋简就繁,就是为了尝试一下DMAJ。

首先我们在SOPC Builder中增加一个名字为dma_0的DMA设备。两个表单设置都选默认。

第二步,DMA设备有三个PORT,两个MASTER PORT:read_master、write_master,一个SLAVE PORT:control_port_slave。需要在SOPC BUILDER中设置AVALONE交换总线,设置read_master和sdram连接,write_master和on_chip_memory连接,具体见下图(交叉点为黑色)。

在sopc builder中生成系统,并在Quartus II中编译下载,硬件部分就OK了。如果你的DMA操作不是内存到内存的,而是内存到设备,或者设备到内存,那么你需要在上面这一步中加以设置,设备只支持读写,是CPU读写还是DMA读写设备不加以区分。

在程序中,我们要使用DMA必须包含:sys/alt_dma.h。

因为是内存DMA操作,所以我们必须实现transmit channels和receive channels,这在NIOS II中就是打开两个设备。在NIOS II IDE中生成一个以Hello World为模板的memory_dma工程项目修改一下程序如下: #include #include #include #include “system.h” static volatile int rx_done = 0;/* * Callback function that obtains notification that the data has * been received.*/ static void done(void* handle, void* data){ rx_done++;} int main(int argc, char* argv[], char* envp[]){ int rc;static char buff[256];alt_dma_txchan txchan;alt_dma_rxchan rxchan;void* tx_data =(void*)buff;/* pointer to data to send */ void* rx_buffer =(void*)0x01000000;/* on_chip_memory addr*/

/* Create the transmit channel */ if((txchan = alt_dma_txchan_open(“/dev/dma_0”))== NULL){ printf(“Failed to open transmit channeln”);exit(1);} /* Create the receive channel */ if((rxchan = alt_dma_rxchan_open(“/dev/dma_0”))== NULL){ printf(“Failed to open receive channeln”);exit(1);} /* Post the transmit request */ if((rc = alt_dma_txchan_send(txchan, tx_data, 128, NULL, NULL))

/* Post the receive request */ if((rc = alt_dma_rxchan_prepare(rxchan, rx_buffer, 128, done, NULL))

/* wait for transfer to complete */ while(!rx_done);printf(“Transfer succeful!n”);return 0;} 我们很多人对DMA理解的很深入,在其他嵌入式领域有丰富的经验,在其他系统上的实现问题很自然会想在NIOS II中是怎么完成的呢,比如DMA完成以后需要中断吗?如何知道DMA传输完成等等,在上面的程序中,实际上是通过回调函数完成的,回调函数在Windows系统的WIN API中以及驱动开发中被大量使用。

好了,DMA就是如此,还有一些相关的函数需要去尝试一下。尝试非常重要,在资料欠缺的时候,需要创建环境去实验,你的理解是这样的,按这样的理解会有这样的结果,实际做一下到底是怎样的,不符合?是理解错了吗?不断尝试,收益无限

《DMA传输小结.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
DMA传输小结
点击下载文档
相关专题 dma传输方式 小结 DMA dma传输方式 小结 DMA
[其他工作总结]相关推荐
    [其他工作总结]热门文章
      下载全文