今天小编要和大家分享的是EDMA组成 EDMA控制机制,接下来我将从EDMA的组成,EDMA的控制机制,EDMA的传输操作,EDMA程序,这几个方面来介绍。
EDMA控制器可以独立于CPU处理L2 Cache/SRAM和C64x外设之间的数据传输,包括:Cache服务、非Cache存储器存取、用户编程的数据传输和主机(host)存取等。所谓“通道”并不是指物理传输通道(EDMA控制器、DMA总线),而是指不同内容(传输源地址、目的地址、传输数量、触发方式等)的DMA传输。用户在系统初始化时可事先设置好许多不同的DMA通道,以便实际运行时可以一个接一个地进行不同的DMA传输,而不必临时再设置通道。
EDMA的组成
EDMA控制器由以下部分组成:
事件和中断处理寄存器
事件编码器
参数RAM
硬件地址产生器
事件寄存器完成对EDMA事件的捕获、控制。若有多个事件同时发生,由事件编码器对它们进行处理(将同时发生的事件进行排队)。
参数RAM存放与事件相关(各通道)的传输参数;这些参数送入硬件地址发生器以产生对EMIF/外设的存取地址。
EDMA的控制机制
1、事件与事件控制寄存器
EDMA有64个通道.每1个通道都有1个事件与之关联.由这些事件触发相应通道的传输。
2、传输参数与参数RAM
EDMA控制器与DMA控制器在结构上有所区别。C64x的.EDMA控制器是基于RAM结构。参数.RAM(parameterRAM。paRAM)的容量是2KB,总共可以存放85组EDMA传输控制参数。多组参数还可以彼此连接起来,从而实现某些负责数据流的传输.例如循环缓存和数据排序等。参数RAM中保存的内容包括:
64个EDMA通道对应的入口传输参数.每组参数包括6个字;
用于重加载,链接的传输参数组。每组参数包括24字节;
8字节空余的RAM可以作为“草稿区”(scratchpadarea)。
一旦捕获到某个事件.控制器将从paRAM顶部的64组入口参数中读取数据对应的控制参数送往地址发生器硬件。
表1给出1组EDMA传输参数的内部结构,总共6个字.192bit。可以通过32bit的外设总线对EDMA的参数.RAM进行访问。
可选参数(Optionparameter),32bit,用户可以根据情况选择设置该参数。
SRC/DST地址.32bit,用于存放EDMA访问起始的源地址和目的地址,可以通过可选参数中的SUM/DUM位设定对SRC/DST地址的修改方式。
数据单元计数(ElementCount),16bit无符号数.存放l帧(1一D传输)或1个阵列(2一D传输)中的数据单元数。
帧/阵列计数(Frame/ArrayCount),16bit无符号数.存放的是1-D数据传输中的帧计数,或是2一D数据传输中的阵列计数。
数据单元,帧,阵列索引(Element/Frame/ArrayIndex).16bit无符号数,作为地址修改的索引值。数据单元索引只应用于1-D传输,为下一数据单元的地址偏移值(2一D传输不允许数据单元间隔存放)。帧,阵列索引用于控制下一帧,阵列的地址索引。
数据计数的重加载(ElementCountReload),16bit无符号数。用于在每帧最后一个数据元素传输之后.重新加载传输计数值。这个参数只能用于1一D传输中。
链接地址(LinkAddress),16bit。当设定可选参数中的LINK=1时,可以由链接地址确定下1个EDMA事件采用参数的装载,重装载地址,从而使多组EDMA传输参数形成EDMA传输链。
EDMA的传输操作
EDMA进行数据传输时有2种启动方式,1种是CpU启动.另1种是由同步事件触发。每1个通道的启动是相互独立的。
1、CpU启动EDMA/非同步的EDMA
CpU可以通过写事件置位寄存器(ESR)启动1个EDMA通道。向ESR中某1位写1时,将强行触发对应的事件。此时,与正常的事件响应过程类似,EDMA的paRAM中的传输参数被送入地址发生器.完成对EMIF、L2存储器或外设的存取访问。由CpU启动的EDMA属于非同步的数据传输。EER中的事件使能与否不会影响这种EDMA传输的启动。
2、由事件触发EDMA
一旦事件编码器捕获到1个触发事件并锁存在ER寄存器中,将导致paRAM中对应的参数被送入地址发生器.进而执行有关的传输操作。尽管是由事件启动传输操作,但是事件本身必须首先被CpU使能。EER寄存器负责控制事件的使能。触发EDMA传输的同步事件可以源于外设,外部器件的中断或某个EDMA通道结束。与DMA的情况不同,与EDMA的每1个通道相关联的触发事件是固定的。因此,如果假设EER中的EVT4=1,那么EXT_INT4引脚的外部中断信号就会启动EDMA通道4的传输。所以,每个事件也就指定了1个特定的EDMA通道。
EDMA程序
此例为对csl的直接调用。
实现功能:打开并初始化EDMA_CHA_GpINT11通道,使用寄存器配置方式从src到dst数据表格的拷贝。
传输数据量:16个16位单字。
myhedma=EDMA_open(EDMA_CHA_GpINT11,EDMA_OpEN_RESET);
//openedma.
EDMA_config(myhedma,&myconfig);
//configureedma.
EDMA_enableChannel(myhedma);
打开并配置edma。
因edma与dma不同,他基于事件触发,所以我们手工写edma事件置位寄存器让其工作。如下
EDMA_setChannel(myhedma);
等待EVM642_wait(1000);
最后检验是否被正确搬移并关闭edma
for(I=0;I<=N-1;I++){
if(dst[I]!=0xBEEFu)
{++err;}
EDMA_close(myhedma);
点击ccs的view菜单的watchwindow,打开watchwindow窗口,运行程序,在watch1下输入src及dst可以看到已正确拷贝。
TIMER程序
本程序从ASK_DEFAULT,
IRQ_IEMASK_DEFAULT
};
第一个为中断函数地址,Thisistheaddressoftheinterruptserviceroutinetobecalledwhentheinterrupthappens.ThisfunctionmustbeC-callableandmustNOTbedeclaredusingtheinterruptkeyword.
第二个为函数传递参数。第3个为Cachecontrolmask:决定DSp/BIOSdispatcher处理cache设置,可选模式具体见csl文档。
。第4个Interruptenablemask。决定处理中断时howinterruptsaremasked。有三种选择
UseIRQ_IEMASK_ALLtomaskoutallinterruptsincludingself,屏蔽所有中断,useIRQ_IEMASK_SELFtomaskself(preventanISRfrompreemptingitself),orusethedefaultwhichisthesameasIRQ_IEMASK_SELF。
IRQ_setVecs(myIvtTable);
设置中断向量基地址
eventId=TIMER_getEventId(hTimer1);
获取timer1的irq事件id号。
IRQ_config(eventId,&myConfig);
配置该irq。
IRQ_enable(eventId);
IRQ_globalEnable();
使能中断。
该程序中的timer1在dsp/bios中的配置如上一程序。
interruptvoidmyIsr()
上面指定的中断函数。注意前面应加上interrupt。程序中为空,可以根据需要加上相关代码。
mian.c代码
#include<csl.h>
#include<csl_irq.h>
#include<csl_timer.h>
#include"Config1cfg.h"
#defineNVECTORS256
#pragmaDATA_SECTION(myIvtTable,".myvec")
intmyIvtTable[NVECTORS];
interruptvoidmyIsr();
IRQ_ConfigmyConfig={
myIsr,
0x00000000,
IRQ_CCMASK_DEFAULT,
IRQ_IEMASK_DEFAULT
};
main(){
Uint16eventId;
intold_intm;
old_intm=IRQ_globalDisable();
IRQ_setVecs(myIvtTable);
eventId=TIMER_getEventId(hTimer1);
IRQ_config(eventId,&myConfig);
IRQ_clear(eventId);
IRQ_enable(eventId);
IRQ_globalRestore(old_intm);
TIMER_start(hTimer1);
IRQ_globalEnable();
}
interruptvoidmyIsr()
{
}
Config1cfg.h代码
/*Do*not*directlymodifythisfile.Itwas*/
/*generatedbytheConfigurationTool;any*/
/*changesriskbeingoverwritten.*/
/*INpUTConfig1.cdb*/
#defineCHIp_DM6421
/*IncludeHeaderFiles*/
#include<std.h>
#include<hst.h>
#include<swi.h>
#include<tsk.h>
#include<log.h>
#include<sts.h>
#ifdef__cplusplus
extern"C"{
#endif
externfarHST_ObjRTA_fromHost;
externfarHST_ObjRTA_toHost;
externfarSWI_ObjKNL_swi;
externfarSWI_ObjSWI0;
externfarTSK_ObjTSK_idle;
externfarLOG_ObjLOG_system;
externfarSTS_ObjIDL_busyObj;
externfarvoidCSL_cfgInit();
#ifdef__cplusplus
}
#endif/*extern"C"*/
Config1cfg_c.c代码
/*Do*not*directlymodifythisfile.Itwas*/
/*generatedbytheConfigurationTool;any*/
/*changesriskbeingoverwritten.*/
/*INpUTConfig1.cdb*/
/*IncludeHeaderFile*/
#include"Config1cfg.h"
#ifdef__cplusplus
#pragmaCODE_SECTION(".text:CSL_cfgInit")
#else
#pragmaCODE_SECTION(CSL_cfgInit,".text:CSL_cfgInit")
#endif
#ifdef__cplusplus
#pragmaFUNC_EXT_CALLED()
#else
#pragmaFUNC_EXT_CALLED(CSL_cfgInit)
#endif
/*ConfigStructures*/
/*Handles*/
/*
*========CSL_cfgInit()========
*/
voidCSL_cfgInit()
{
}
main.c代码
#include<csl.h>
#include<csl_edma.h>
#defineN16
#pragmaDATA_SECTION(src,".damMem")
//pUTSRCINDMAMEMSECTION
#pragmaDATA_ALIGN(src,256)
//alignsrc
Uint16src[N]={
0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,
0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,};
#pragmaDATA_SECTION(dst,".dmaMem")
Uint16dst[N];
EDMA_Configmyconfig={
EDMA_OpT_RMK(
EDMA_OpT_pRI_LOW,//edmaprivilege
EDMA_OpT_ESIZE_16BIT,//
EDMA_OpT_2DS_NO,
EDMA_OpT_SUM_INC,
EDMA_OpT_2DD_NO,
EDMA_OpT_DUM_INC,
EDMA_OpT_TCINT_NO,
EDMA_OpT_TCC_OF(0),
EDMA_OpT_TCCM_OF(0),
EDMA_OpT_ATCINT_NO,
EDMA_OpT_ATCC_OF(0),
EDMA_OpT_pDTS_DEFAULT,
EDMA_OpT_pDTD_DEFAULT,
EDMA_OpT_LINK_NO,
EDMA_OpT_FS_YES
),
EDMA_SRC_OF(&src[0]),
EDMA_CNT_OF(N),
EDMA_DST_OF(&dst[0]),
EDMA_IDX_OF(0x00000002),
EDMA_RLD_OF(0x00000000)
};
//parameterofedma
voidtaskFunc(void);
//announceoftask
voidmain(){
CSL_init();
//ifyouwanttousecslmodules,csl_init()functionmustbecalledfirst.
taskFunc();
//starttaskfunc()
}
voidtaskFunc(void){
Uint16err=0;
//thenumberofwrongmember
Uint16I;
EDMA_Handlemyhedma;
//edmahandle
myhedma=EDMA_open(EDMA_CHA_GpINT11,EDMA_OpEN_RESET);
//openedma.
EDMA_config(myhedma,&myconfig);
//configureedma.
EDMA_enableChannel(myhedma);
EDMA_setChannel(myhedma);
//softtriggeranEDMAchannel
EVMDM642_wait(1000);
//wait
for(I=0;I<=N-1;I++){
if(dst[I]!=0xBEEFu)
{++err;}
//judge
}
EDMA_close(myhedma);//closetheedma
}
关于EDMA,电子元器件资料就介绍完了,您有什么想法可以联系小编。