怎样给每个核分配不同的channel,然后设置不同的参数。然后多核同时传输数据“Channels and parameter RAM can be separated by software into regions, with each
region assigned to a core.”这是多核里的一句话,现在就是不明白怎么样让EDMA分成多个channel!!!!
急求!!!!!
毕设没时间了!!!!!
Zhan Xiang:
1. 涅磐了就离成功不远了,这句话应该这么理解:首先EDMA的的channel对应到系统中就是一个能够触发EDMA传输的事件,当系统中该事件产生后,对应的EDMA channle controller就会收到这个事件的信号,此时EDMA控制器会根据配置来判断是不是要进行数据传输,如果产生的事件被使能了,那么EDMA控制器就会把传输请求向后面的处理模块提交,这里就用到了parameter RAM(PaRAM),EDMA会根据PaRAM定义的源地址,目的地址,数据长度和传输方式进行传输。
2. 以上就是一个EDMA传输的基本过程,因为EDMA传输事件(channel)是多core共享的,如果一个EDMA传输事件只想某一个core来响应,而其他core不去响应,就要用到region的概念。每个EDMA控制器可以分成8个region,如果要使用对应的region,那么就需要配置DRAE和DRAEH寄存器,这两个寄存器每个bit代表一个EDMA 传输事件,如果置1,那么当系统中该事件产生时,对应region就会去响应这个EDMA传输事件,如果为0,那么即便系统中产生了该EDMA传输事件,所使用的region也不会去响应这个事件,这样就能让多核将共享的EDMA传输事件按需分配。
3. 另外PaRAM是所有EDMA传输事件共享的,在6678中只有3个EDMA控制器,如果有多个core共享一个EDMA控制器,那么PaRAM也要共享,所以要按照region分配的EDMA传输事件将PaRAM进行划分,保证不同EDMA传输事件不共享同一个PaRAM。
Nicole He:
回复 Zhan Xiang:
我大概明白了,又还是有不明白的。可能跟原来没有DSP开发经验,也没有相关的DSP培训课程有关吧….对于DSP一头雾水。看了手册,把自己的程序改成这个样子(原来7个核都是用了region_global)现在一个核用一个region
如:
CSL_Edma3Obj edmaObj; CSL_Edma3ChannelObj chObj; CSL_Edma3CmdIntr regionIntr; CSL_Edma3Context context; CSL_Edma3ChannelAttr chAttr; CSL_Status status;
unsigned char channelNum = 0; unsigned char instNum = 1;
//initialize the edma3
CSL_edma3Init(&context);
hMoudle = CSL_edma3Open(&edmaObj,instNum,NULL,&status);
chAttr.regionNum = CSL_EDMA3_REGION_0 ;
chAttr.chaNum = channelNum;//channel number是0因为原来那个程序就是那样的,我也没敢动
hChannel = CSL_edma3ChannelOpen(&chObj,instNum,&chAttr,&status);
CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_0);
CSL_edma3MapDMAChannelToParamBlock(hMoudle,channelNum,0);
hParamPing = CSL_edma3GetParamHandle(hChannel,0,&status);
regionIntr.region = CSL_EDMA3_REGION_0;
regionIntr.intr = 0x1;
regionIntr.intrh = 0x0;
CSL_edma3HwControl(hMoudle,CSL_EDMA3_CMD_INTR_ENABLE,®ionIntr);
myParamSetup.option = 0x00100008;//block move
myParamSetup.srcAddr = (Uint32)(srcbuf+(DNUM-1)*64);
myParamSetup.aCntbCnt = 0x00010040;
myParamSetup.dstAddr = (Uint32)(dstbuf+(DNUM-1)*64);
myParamSetup.srcDstBidx = 0x0;
myParamSetup.linkBcntrld = 0x0000ffff;
myParamSetup.srcDstCidx = 0x0;
myParamSetup.cCnt = 0x00000001;
CSL_edma3ParamSetup(hParamPing,&myParamSetup);
CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
regionIntr.region = CSL_EDMA3_REGION_0;
regionIntr.intr = 0x0;
regionIntr.intrh = 0x0;
for(;FLAG_TAG!=1;){}
do
{
CSL_edma3GetHwStatus(hMoudle,CSL_EDMA3_QUERY_INTRPEND,®ionIntr);
}
while (!(regionIntr.intr & 0x1));
CSL_edma3HwControl(hMoudle,CSL_EDMA3_CMD_INTRPEND_CLEAR,®ionIntr);
CSL_edma3ChannelClose(hChannel);
CSL_edma3Close(hMoudle);
现在的情况是EDMA不能搬数了…您知道是为什么吗,跟我改错了参数有关,那么如果我要不同的核用不同的region应该怎么改呢?(我的CSL的paraRAM的vector放在了各自核的L2SRAM里,应该不影响吧就是在.cmd的地方写的。)
谢谢了~真是大好人!!!!
Richard Zhang:
回复 Nicole He:
你是想多核同时操作EDMA吗?给你提几个建议
1。我觉得其实你的程序里红色的部分,也就是region,可改可不改,多核同时用global region操作不会有问题的,可以熟悉了以后再改。
2。多核同时操作,关键点是要使用不同的EMDA chanel 和EDMA PaRAM。所以你需要改的地方是这。
chAttr.chaNum = corenumber;// 这里的 channelNum 可以改成corenumber 表示使用不同的chanel
CSL_edma3MapDMAChannelToParamBlock(hMoudle,corenumber,corenumber);//这里把不同的chanel映射到不同的PaRAM
hParamPing = CSL_edma3GetParamHandle(hChannel,corenumber,&status);//这里设置不同的PaRAM
设置就这些,总之保证每个核使用不同的chanel和PaRAM就可以。传输的时候根据不同的通道设置一下ESR寄存器相应位手动触发EDMA同步事件 就可以了。
3. paraRAM使用的地址是固定的~ 是一个全局地址 多核都可以操作的 我记得是EDMA0的 是0x02704000开始
EDMA1的 是0x02724000开始.这个你分配的是没用的。
Nicole He:
回复 Richard Zhang:
我又小白了…"传输的时候根据不同的通道设置一下ESR寄存器相应位手动触发EDMA同步事件 就可以了。"弱弱的问一下怎么设置ESR相应位呢?
我知道手动触发是
regionIntr.region = CSL_EDMA3_REGION_0;
regionIntr.intr = 0x0;
regionIntr.intrh = 0x0;
需要设置哪个呢???
谢谢啦!!!!!超级感谢!!!!
Richard Zhang:
回复 Nicole He:
你说的这三个是设置中断使能的~
设置同步事件的语句是这个。
CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
有的问题你直接在文档里一搜就有答案了。比如XX寄存器是做什么用的。。
xinxin lai:
你好,我现在也想用八个核同时传输数据,按照你那样改,每个核用不同的通道,但是只能两个核同时传数据,核数多了就会出错,能不能说下你后面怎么弄的,非常感谢,
xinxin lai:
回复 Nicole He:
void Edma1(double *srcadd,double *dstadd,Uint32 abCnt,Uint32 sdBidx,Uint32 channelNum){ CSL_Edma3ParamHandle hParamPing0; CSL_Edma3ParamSetup myParamSetup0; //参数列表00 CSL_Edma3ChannelHandle hChannel0; CSL_Edma3Handle hMoudle0; //dma or qdma CSL_Edma3Obj edmaObj; CSL_Edma3ChannelObj chObj; CSL_Edma3CmdIntr regionIntr; CSL_Edma3Context context; CSL_Edma3ChannelAttr chAttr; CSL_Status status;
// unsigned int start,end;
// start=TSCL;
// unsigned char channelNum = 0; //通道号 unsigned char instNum = 0; //TPCC0 通道控制器
CSL_edma3Init(&context); //初始化
hMoudle0 = CSL_edma3Open(&edmaObj,instNum,NULL,&status); //module level open
chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL; chAttr.chaNum = channelNum; // Channel number 改这个通道号为核号 hChannel0 = CSL_edma3ChannelOpen(&chObj,instNum,&chAttr,&status);
CSL_edma3HwChannelSetupQue(hChannel0,CSL_EDMA3_QUE_0); //将TPCC0的通道对应事件队列对应核号
CSL_edma3MapDMAChannelToParamBlock(hMoudle0,channelNum,channelNum);//使用DMA通道,通道0对应para0
hParamPing0 = CSL_edma3GetParamHandle(hChannel0,channelNum,&status); //param句柄
regionIntr.region = CSL_EDMA3_REGION_GLOBAL; regionIntr.intr = 0x1; regionIntr.intrh = 0x0; CSL_edma3HwControl(hMoudle0,CSL_EDMA3_CMD_INTR_ENABLE,®ionIntr); //使能中断//EDMA to core 0 myParamSetup0.option = 0x0010000c; myParamSetup0.srcAddr = (Uint32)srcadd; myParamSetup0.aCntbCnt = (Uint32)abCnt; myParamSetup0.dstAddr = (Uint32)dstadd; myParamSetup0.srcDstBidx = (Uint32)sdBidx; myParamSetup0.linkBcntrld = 0x0000ffff; myParamSetup0.srcDstCidx = 0x0; myParamSetup0.cCnt = 0x00000001;
CSL_edma3ParamSetup(hParamPing0,&myParamSetup0); //设置para0
CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_SET,NULL); //手动设置通道事件,写入ESR
regionIntr.region = CSL_EDMA3_REGION_GLOBAL; regionIntr.intr = 0x0; regionIntr.intrh = 0x0; do { CSL_edma3GetHwStatus(hMoudle0,CSL_EDMA3_QUERY_INTRPEND,®ionIntr);//读取IPR寄存器 } while (!(regionIntr.intr & 0x1));
CSL_edma3HwControl(hMoudle0,CSL_EDMA3_CMD_INTRPEND_CLEAR,®ionIntr);//通过ICR清除IPR相应位
CSL_edma3ChannelClose(hChannel0);
CSL_edma3Close(hMoudle0);}
想八个核调用这个函数,参数是不同的核号,地址,和数据长度,
很急!!!!!