menDMA实验.docx
《menDMA实验.docx》由会员分享,可在线阅读,更多相关《menDMA实验.docx(15页珍藏版)》请在冰豆网上搜索。
menDMA实验
基于描述符的存储器DMA实验
本实验利用ADSPBF533-EZ-KIT板的硬件资源,完成Blackfin存储空间中的存储器对存储器的DMA传送。
本实验中三种不同的描述符(DMA传送方法)得到的结果不一样,可以通过观察各个输出存储器的窗口看到现象。
通过这个实验可以加深对menDMA数据传送方式的理解。
1.本实验程序简介
1)程序结构:
程序包括主函数main.asm、memDMAfunc.asm、memdmainit.asm等3个模块,以及常数和宏定义、全局变量定义部分。
其中main.asm函数完成整个功能程序的控制,memDMAfunc.asm完成各种描述符(DMA数据传送方法)的设定和dma_engine的启动,memdmainit.asm完成基于描述的DMA初始化。
2)程序工作流程:
_main先调用memdma_init完成对基于描述的DMA初始化,再调用memdma_move1D、callmemdma_move1Dto2D、memdma_move2Dto2D三种不同的描述符(传送方法)进行存储器到存储器的数据传送,最后调用ctivate_dma_engine启动DMA传送数据。
本实验的程序位于…\DescriptorBase子目录,打开工程文件memdma_example.dpj,可以看到演示软件包括以下几个程序模块:
(1)main.asm
#include"defBF533.h"
#defineN0x100//numberofelementstotransferineachDMAexample
//Defineexternfunctions
.externmemdma_init;
.externactivate_dma_engine;
.externmemdma_move1D;
.externmemdma_move1Dto2D;
.externmemdma_move2Dto2D;
//SetupinputandoutputbuffersinL1databankA
.sectionL1_data_a;
.align4;
.globalinput_frame;
input_frame:
.byte_input_frame[N]="input_data.dat";//loadin256valuesfromatestfile
input_frame.end:
.globaloutput_frame_1Dto1D;//outputbufferafter1Dto1DDMA
output_frame_1Dto1D:
.byte_output_frame_1Dto1D[N];
output_frame_1Dto1D.end:
.globaloutput_frame_1Dto2D;//outputbufferafter1Dto2DDMA
output_frame_1Dto2D:
.byte_output_frame_1Dto2D[N];
output_frame_1Dto2D.end:
.globaloutput_frame_2Dto2D;//outputbufferafter2Dto2DDMA
output_frame_2Dto2D:
.byte_output_frame_2Dto2D[N];
output_frame_2Dto2D.end:
.sectionL1_code;
.align4;
.global_main;
_main:
callmemdma_init;//setupdescriptorframework
//Inthethisexample,3descriptorsetsarebuilt.
//Ineachcase,thedataregistersareusedtostorethefollowingDMAinfo
//priortomakingthesetupcall
//r0->srcaddress
//r1->XCNT/XMOD
//r2->YCNT/YMOD
//r3->DstAddr
r0.h=input_frame;//sourceaddress
r0.l=input_frame;
r1.l=N>>2;//XCNT->100bytes
r1.h=4;//XMOD=4bytes-32bitxfers
//XMODhastobeatleast4since32-bittransfersareused
r3.h=output_frame_1Dto1D;//DestinationAddressforfirstdescriptor
r3.l=output_frame_1Dto1D;
callmemdma_move1D;//setup1Dto1DL1->L1descriptor
r0.h=input_frame;//sourceaddress
r0.l=input_frame;
r1.l=0x0002;//D_XCNT-2columns
r1.h=0x0004;//D_XMOD=4bytes(32bittransfers)
r2.l=0x0003;//YCNT->3rows
r2.h=0x0010;//YMOD-16bytes(producesaseparationof12bytes(16-4)betweeneachblock)
r3.h=output_frame_1Dto2D;//DestinationAddress
r3.l=output_frame_1Dto2D;
callmemdma_move1Dto2D;//setup1Dto2DL1->L1descriptor
r0.h=input_frame;//sourceaddress
r0.l=input_frame;
r1.l=0x0002;//SandD_XCNT-2columns;
r1.h=0x0004;//SandD_XMOD=4bytes-132bitelement
r2.l=0x0003;//SandDYCNT->2rows;
r2.h=0x0010;//SandDYMOD-16bytes
r3.h=output_frame_2Dto2D;//DestinationAddress
r3.l=output_frame_2Dto2D;
callmemdma_move2Dto2D;//setup2Dto2DL1->L1descriptor
callactivate_dma_engine;//startdescriptorbasedDMA
//OpenamemorywindowandlookatthefollowinglabelstoseetheresultsofeachDMA
//output_frame_1Dto1D
//output_frame_1Dto2D
//output_frame_2Dto2D:
here:
jumphere;//Exampledone
_main.end:
(2)memdmainit.asm
#include"defBF533.h"
/***************************************************************
MemDmainitializationroutine
Thisroutinesetsupthedescriptorlistframework
foramemDMAtransferuptoNUM_DESCR_BLOCKS_IN_QUEUEdescriptors
AsourceanddestinationbufferissetupbecausememDMAisbeingused
***************************************************************/
#include"memdma.h"
.sectionL1_data_a;
.align4;
//DMADescriptor-SmallModel
//132BWord:
LS16BW:
NextDescrPointer,MS16BW:
StartAddrLow
//232BWord:
LS16BW:
StartAddrHigh,MS16BW:
DMAconfig
//332BWord:
LS16BW:
XCNT,MS16BW:
XMOD
//432BWord:
LS16BW:
YCNT,MS16BW:
YMOD
.globalMemDMAQueue;
MemDMAQueue:
.byte4_MemDMAQueue[4*2*NUM_DESCR_BLOCKS_IN_QUEUE];//832bitwords*NUM_DESCR_IN_QUEUE
MemDMAQueue.end:
.sectionL1_code;
.align4;
//dummy_start:
.globalmemdma_init;
memdma_init:
//Thisroutinesetsupadescriptorframework
//Eachdescriptorisfilledinfromcallswithinmain.asm
p1.h=MemDMAQueue;
p1.l=MemDMAQueue;
p2=16(z);
r0=p1;
r1=p1;
r0+=16;
p0=((NUM_DESCR_BLOCKS_IN_QUEUE-1)*2);
lsetup(start_memdmaqueueinit,end_memdmaqueueinit)lc0=p0;
start_memdmaqueueinit:
r0+=16;
end_memdmaqueueinit:
w[p1++p2]=r0.l;
//LastDescriptorintheQueuepointstothefirstone
w[p1++p2]=r1.l;
r1+=16;
[p1]=r1;
rts;
memdma_init.end:
(3)memDMAfunc.asm
******************************************************************************/
#include"defBF533.h"
/*****************************************************************************
MemDmaroutines
dmaDescrPtr=memdma_move1Dto2D(srcaddr,xcount,ycount,dstaddr,[priority])
dmaDescrPtr=memdma_move2Dto1D(srcaddr,xcount,ycount,dstaddr,[priority])
dmaDescrPtr=memdma_move1D(srcaddr(32b),count(32b),destaddr(32b),[priority])
memdma_wait(dmaDescrPtr)
******************************************************************************/
#include"memdma.h"
#defineNUM_QUEUE_STRUCT_ELEM2
//Alloftheseareconfiguredasdescriptorlist(smallmodel)0x6inupperbyte
//Descriptorsize=8
//allaresetto32-bittransfers
//allaresettoDMAenable
#defineSRCMEM1DCFG0x6809//DMAread
#defineSRCMEM2DCFG0x6819//2Dbitset,DMAread
#defineDSTMEM1DCFG0x680B//DMAwrite
#defineDSTMEM2DCFG0x681B//2Dbitset,DMAwrite
//DMADescriptor(S&D)-SmallModel
//132BWord:
LS16BW:
SrcNDPL,MS16BW:
SrcSAL+0
//232BWord:
LS16BW:
SrcSAH,MS16BW:
SrcDMACFG+4
//332BWord:
LS16BW:
SrcXCNT,MS16BW:
SrcXMOD+8
//432BWord:
LS16BW:
SrcYCNT,MS16BW:
SrcYMOD+12
//632BWord:
LS16BW:
DstNDPL,MS16BW:
DstSAL+16
//732BWord:
LS16BW:
DstSAH,MS16BW:
DstDMACFG+20
//832BWord:
LS16BW:
DstXCNT,MS16BW:
DstXMOD+24
//932BWord:
LS16BW:
DstYCNT,MS16BW:
DstYMOD+28
.externMemDMAQueue;
.externmemdma_move1D_buffer;//setsupdescriptorsfor1Dtransfer
//.sectionshell_L1_data;
.sectionL1_data_a;
.align4;
//.sectionshell_L1_data;
.sectionL1_data_a;
.align4;
MemDMAQueueStruct:
.byte4_MemDMAQueueStruct[NUM_QUEUE_STRUCT_ELEM]=MemDMAQueue,
MemDMAQueue;
.sectionL1_code;
.align4;
//dummy_start:
.globalmemdma_move1Dto2D;//setsup1Dto2Ddescriptor
memdma_move1Dto2D:
p1.h=MemDMAQueueStruct;
p1.l=MemDMAQueueStruct;
r5=[p1++];//tailaddress
i0=r5;
r4=[p1--];//MemDMAQueuestartaddress
b0=r4;
l0=NUM_DESCR_BLOCKS_IN_QUEUE*32(z);
m0=8;
nop;
r4.l=w[i0++];//S_NDPL->dummyread
w[i0++]=r0.l;//S_SAL
w[i0++]=r0.h;//S_SAH
r0.l=SRCMEM1DCFG;
w[i0++]=r0.l;//S_CFG
r0=r1;//S_XMOD=D_XMOD
r0.l=r1.l*r2.l(IU);//S_XCNT=D_XCNT*D_YCNT
[i0++m0]=r0;//S_XCNT/S_XMOD
r4.l=w[i0++];//D_NDPL->dummyread
w[i0++]=r3.l;//D_SAL
w[i0++]=r3.h;//D_SAH
r0.l=DSTMEM2DCFG;
w[i0++]=r0.l;//D_CFG
[i0++]=r1;//D_XCNT/D_XMOD
[i0++]=r2;//D_YCNT/D_YMOD
l0=0;
r0=i0;
[p1]=r0;//updatetailwithNDPvalue
r0=r5;//r0-returnparameter
rts;
memdma_move1Dto2D.end:
.globalmemdma_move2Dto2D;//setsup2Dto2Ddescriptor
memdma_move2Dto2D:
p1.h=MemDMAQueueStruct;
p1.l=MemDMAQueueStruct;
r5=[p1++];//tailaddress
i0=r5;
r4=[p1--];//MemDMAQueuestartaddress
b0=r4;
l0=NUM_DESCR_BLOCKS_IN_QUEUE*32(z);
m0=8;
nop;
r4.l=w[i0++];//S_NDPL->dummyread
w[i0++]=r0.l;//S_SAL
w[i0++]=r0.h;//S_SAH
r0.l=SRCMEM2DCFG;
w[i0++]=r0.l;//D_CFG
[i0++]=r1;//D_XCNT/D_XMOD
[i0++]=r2;//D_YCNT/D_YMOD
#if0
w[i0++]=r0.l;//S_CFG
r0=r1;//S_XMOD=D_XMOD
r0.l=r1.l*r2.l(IU);//S_XCNT=D_XCNT*D_YCNT
[i0++m0]=r0;//S_XCNT/S_XMOD
#endif
r4.l=w[i0++];//D_NDPL->dummyread
w[i0++]=r3.l;//D_SAL
w[i0++]=r3.h;//D_SAH
r0.l=DSTMEM2DCFG;
w[i0++]=r0.l;//D_CFG
[i0++]=r1;//D_XCNT/D_XMOD
[i0++]=r2;//D_YCNT/D_YMOD
l0=0;
r0=i0;
[p1]=r0;//updatetailwithNDPvalue
r0=r5;//r0-returnparameter
rts;
memdma_move2Dto2D.end:
//r0->srcaddress
//r1->XCNT/XMOD
//r2->YCNT/YMOD
//r3->DstAddr
.globalmemdma_move1D;//setsup1Dto1Ddescriptor
memdma_move1D:
p1.h=MemDMAQueueStruct;
p1.l=MemDMAQueueStruct;
r5=[p1++];//tailaddress
i0=r5;
r4=[p1--];//MemDMAQueuestartaddress
b0=r4;
l0=NUM_DESCR_BLOCKS_IN_QUEUE*32(z);
m0=8;
nop;
r4.l=w[i0++];//dummyreadtooffsetNDPL
w[i0++]=r0.l;//S_SAL
w[i0++]=r0.h;//S_SAH
r0.l=SRCMEM1DCFG;
w[i0++]=r0.l;//S_CFG
[i0++m0]=r1;//S_XCNT/S_XMOD
r4.l=w[i0++];//dummyreadtogetoverDSTNDPL
w[i0++]=r3.l;//D_SAL
w[i0++]=r3.h;//D_SAH
r3.l=DSTMEM1DCFG;
w[i0++]=r3.l;//D_CFG
[i0++m0]=r1;//D_XCNT/D_XMOD
l0=0;
r0=i0;
[p1]=r0;//updatetailwithNDPvalue
r0=r5;//r0-returnparameter
rts;
memdma_move1D.end:
.globalactivate_dma_engine;
activate_dma_engine:
//oncedescriptorlistisset,callthistostartDMA
p0.h=HI(MDMA_S0_NEXT_DESC_PTR);
p0.l=LO(MDMA_S0_NEXT_DESC_PTR);
r0.l=MemDMAQueue;//AddressoftheSourceDescriptor
r0.h=MemDMAQueue;
[p0]=r0;
ssync;
p0.l=LO(MDMA_D0_NEXT_DESC_PTR);
r0+=16;