TI论坛
直播中

陈小鸥

7年用户 209经验值
私信 关注
[问答]

关于6678 多核访问EDMA 冲突问题

您好,
想实现6678 多核访问EDMA,如何做到避免多核冲突。目前做法:8核使用不同的region,8核DMA事件用不同的channel。请问还需做哪些工作保证8核用EDMA传输数据时都能正确传送,目前8核分别单核运行都没问题,8核group 运行只有一个核完成传送。
谢谢!

回帖(4)

王英

2018-8-6 09:26:43
使用不同的parameter set,以及中断事件的映射;最好你把两个核上的EDMA配置代码贴出来看看
举报

陈小鸥

2018-8-6 09:32:56
引用: hdfsf 发表于 2018-8-6 09:26
使用不同的parameter set,以及中断事件的映射;最好你把两个核上的EDMA配置代码贴出来看看

您好,部分代码如下
//define EDMA3 instances
#define CSL_EDMA3 CSL_EDMA3CC_1
//region
#define SP_CORE0_EDMA_REGION CSL_EDMA3_REGION_0
#define SP_CORE1_EDMA_REGION CSL_EDMA3_REGION_1
//channel
#define SP_CORE0_FFTDATAIN_EDMA_CHANNEL 33
#define SP_CORE1_FFTDATAIN_EDMA_CHANNEL 34
//tcc
#define SP_CORE0_FFTDATAIN_EDMA_TCC SP_CORE0_FFTDATAIN_EDMA_CHANNEL //chain to self
#define SP_CORE1_FFTDATAIN_EDMA_TCC SP_CORE1_FFTDATAIN_EDMA_CHANNEL
//param set
#define SP_CORE0_FFTDATAIN_EDMA_PARAM 1
#define SP_CORE1_FFTDATAIN_EDMA_PARAM 2
//queue
#define SP_FFTDATAIN_EDMA_QUE CSL_EDMA3_QUE_0
int edma_config(int core_num)[
CSL_Edma3HwSetup hwSetup;
CSL_Edma3CmdIntr regionIntr;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3ChannelAttr chAttr;
CSL_Status status;
CSL_Edma3HwDmaChannelSetup dmahwSetup[64];
CSL_Edma3CmdQuePri que_pri;
//--------------global edma setup---------------//
status = CSL_edma3Init(NULL);
if (status != CSL_SOK) [
DEBUG1("Edma module initialization failedn");
return SP_FAIL;
]
hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
if ( (hModule == NULL) || (status != CSL_SOK)) [
DEBUG1 ("Edma module open failedn");
return SP_FAIL;
]
if(core_num == 0)[
dmahwSetup[SP_CORE0_FFTDATAIN_EDMA_CHANNEL].paramNum = SP_CORE0_FFTDATAIN_EDMA_PARAM;
dmahwSetup[SP_CORE0_FFTDATAIN_EDMA_CHANNEL].que = SP_FFTDATAIN_EDMA_QUE;


//FFTDATAIN Region
regionAccess.region = SP_CORE0_EDMA_REGION ;
regionAccess.drae = 0x0;
regionAccess.draeh = 1 <<(SP_CORE0_FFTDATAIN_EDMA_CHANNEL-32);
//tcc and channel are same. for chaining
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE,®ionAccess);
if (status != CSL_SOK) [
DEBUG1("Edma region enable command failedn");
return SP_FAIL;
]

//---FFTDATAIN CH---//
// Channel open
chAttr.regionNum = SP_CORE0_EDMA_REGION;
chAttr.chaNum = SP_CORE0_FFTDATAIN_EDMA_CHANNEL;
hEdmaChannel_FFTDATAIN = CSL_edma3ChannelOpen(&chObj_FFTDATAIN, CSL_EDMA3, &chAttr, &status);
if ( (hEdmaChannel_FFTDATAIN== NULL) || (status != CSL_SOK)) [
DEBUG1 ("Edma channel open failedn");
return SP_FAIL;
]
//Enable channel
status = CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
if (status != CSL_SOK) [
DEBUG1 ("Edma channel enable command failedn");
return SP_FAIL;
]
/* Map the System Interrupt       EDMA3CC1 CCINT0 */
CpIntc_dispatchPlug(8, (CpIntc_FuncPtr)fftdatain_edmacc_core0_isr, (UArg)hEdmaChannel_FFTDATAIN, TRUE);
/* The configuration is for CPINTC0. We map system interrupt x to Host Interrupt y. */
CpIntc_mapSysIntToHostInt(0, 8, 32);
/* Enable the Host Interrupt. */
CpIntc_enableHostInt(0, 32);
/* Enable the System Interrupt */
CpIntc_enableSysInt(0, 8);
// Enable interrupts
regionIntr.region = SP_CORE0_EDMA_REGION ;
regionIntr.intr = 0x0;
regionIntr.intrh = 1<<(SP_CORE0_FFTDATAIN_EDMA_TCC-32);
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,®ionIntr);
if (status != CSL_SOK) [
DEBUG1 ("Edma interrupt enable command failedn");
return SP_FAIL;
]
]
if(core_num == 1)[
dmahwSetup[SP_CORE1_FFTDATAIN_EDMA_CHANNEL].paramNum = SP_CORE1_FFTDATAIN_EDMA_PARAM;
dmahwSetup[SP_CORE1_FFTDATAIN_EDMA_CHANNEL].que = SP_FFTDATAIN_EDMA_QUE;


//FFTDATAIN Region
regionAccess.region = SP_CORE1_EDMA_REGION ;
regionAccess.drae = 0x0;
regionAccess.draeh = 1 <<(SP_CORE1_FFTDATAIN_EDMA_CHANNEL-32);
//tcc and channel are same. for chaining
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE,®ionAccess);
if (status != CSL_SOK) [
DEBUG1("Edma region enable command failedn");
return SP_FAIL;
]
//---FFTDATAIN CH---//
// Channel open
chAttr.regionNum = SP_CORE1_EDMA_REGION;
chAttr.chaNum = SP_CORE1_FFTDATAIN_EDMA_CHANNEL;
hEdmaChannel_FFTDATAIN = CSL_edma3ChannelOpen(&chObj_FFTDATAIN, CSL_EDMA3, &chAttr, &status);
if ( (hEdmaChannel_FFTDATAIN== NULL) || (status != CSL_SOK)) [
DEBUG1 ("Edma channel open failedn");
return SP_FAIL;
]
//Enable channel
status = CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
if (status != CSL_SOK) [
DEBUG1 ("Edma channel enable command failedn");
return SP_FAIL;
]
/* Map the System Interrupt         EDMA3CC1 CCINT0*/
CpIntc_dispatchPlug(8, (CpIntc_FuncPtr)fftdatain_edmacc_core1_isr, (UArg)hEdmaChannel_FFTDATAIN, TRUE);
/* The configuration is for CPINTC0. We map system interrupt x to Host Interrupt y. */
CpIntc_mapSysIntToHostInt(0, 8, 43);
/* Enable the Host Interrupt. */
CpIntc_enableHostInt(0, 43);
/* Enable the System Interrupt */
CpIntc_enableSysInt(0, 8);
// Enable interrupts
regionIntr.region = SP_CORE1_EDMA_REGION ;
regionIntr.intr = 0x0;
regionIntr.intrh = 1<<(SP_CORE1_FFTDATAIN_EDMA_TCC-32);
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,®ionIntr);
if (status != CSL_SOK) [
DEBUG1 ("Edma interrupt enable command failedn");
return SP_FAIL;
]
]
hwSetup.dmaChaSetup = dmahwSetup;
hwSetup.qdmaChaSetup = NULL;
status = CSL_edma3HwSetup(hModule,&hwSetup);
if (status != CSL_SOK) [
DEBUG1 ("Hardware setup failedn");
CSL_edma3Close (hModule);
return SP_FAIL;
]
//Setup queue priority.
que_pri.que = CSL_EDMA3_QUE_0;
que_pri.pri = CSL_EDMA3_QUE_PRI_0;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QUEPRIORITY_SET,(void *)&que_pri);
que_pri.que = CSL_EDMA3_QUE_1;
que_pri.pri = CSL_EDMA3_QUE_PRI_1;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QUEPRIORITY_SET,(void *)&que_pri);
que_pri.que = CSL_EDMA3_QUE_2;
que_pri.pri = CSL_EDMA3_QUE_PRI_2;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QUEPRIORITY_SET,(void *)&que_pri);
que_pri.que = CSL_EDMA3_QUE_3;
que_pri.pri = CSL_EDMA3_QUE_PRI_3;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QUEPRIORITY_SET,(void *)&que_pri);

return SP_OK;
]



///////////////////////////////////////////////////////////////////////////////////////////////////
int setup_fftdatain_edma(fft_dma_ctl_t *dma_ctl,int core_num)[
CSL_Edma3ParamHandle hParamBasic;
CSL_Edma3ParamSetup myParamSetup;
CSL_Status status;
CSL_Edma3ChannelErr chErrClear;
chErrClear.missed = TRUE;
chErrClear.secEvt = TRUE;
CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN, CSL_EDMA3_CMD_CHANNEL_CLEARERR,&chErrClear);
CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);
status = CSL_edma3HwChannelControl (hEdmaChannel_FFTDATAIN,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
/* Get the parameter handle */
if(core_num == 0)[
hParamBasic = CSL_edma3GetParamHandle(hEdmaChannel_FFTDATAIN,SP_CORE0_FFTDATAIN_EDMA_PARAM,&status);
if (hParamBasic == NULL) [
DEBUG1("Edma get param handle failedn");
return SP_FAIL;
]
/* Edma parameter entry Setup */
myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_EN,
CSL_EDMA3_TCCH_DIS,
CSL_EDMA3_ITCINT_DIS,
CSL_EDMA3_TCINT_EN,
SP_CORE0_FFTDATAIN_EDMA_TCC,
CSL_EDMA3_TCC_NORMAL,
CSL_EDMA3_FIFOWIDTH_NONE,
CSL_EDMA3_STATIC_DIS,
CSL_EDMA3_SYNC_AB,
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR);
]
if(core_num == 1)[
hParamBasic = CSL_edma3GetParamHandle(hEdmaChannel_FFTDATAIN,SP_CORE1_FFTDATAIN_EDMA_PARAM,&status);
if (hParamBasic == NULL) [
DEBUG1("Edma get param handle failedn");
return SP_FAIL;
]
/* Edma parameter entry Setup */
myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_EN,
CSL_EDMA3_TCCH_DIS,
CSL_EDMA3_ITCINT_DIS,
CSL_EDMA3_TCINT_EN,
SP_CORE1_FFTDATAIN_EDMA_TCC,
CSL_EDMA3_TCC_NORMAL,
CSL_EDMA3_FIFOWIDTH_NONE,
CSL_EDMA3_STATIC_DIS,
CSL_EDMA3_SYNC_AB,
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR);
]

myParamSetup.srcAddr = GLOBAL_ADDR((Uint32)dma_ctl->src);
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(dma_ctl->acnt,dma_ctl->bcnt);
myParamSetup.dstAddr = GLOBAL_ADDR((Uint32)dma_ctl->dst);
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(dma_ctl->src_bindex,dma_ctl->dst_bindex);
myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,1);
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(dma_ctl->src_cindex,dma_ctl->dst_cindex);
myParamSetup.cCnt = dma_ctl->ccnt;
status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);
if (status != CSL_SOK) [
DEBUG1 ("Edma param setup failedn");
return SP_FAIL;
]
return SP_OK;
]
还有一个问题:就是中断未响应,敬请赐教,工程在BIOS下,edma_config做了CPINTC 的映射配置
Int main()
[
Task_Handle task;
Error_Block eb;
Int intNum;
Hwi_Params params;
System_printf("enter main()n");
edma_config(DNUM);
Error_init(&eb);
task = Task_create(taskFxn, NULL, &eb);
if (task == NULL) [
System_printf("Task_create() failed!n");
BIOS_exit(0);
]
// Initialize the Hwi parameters
Hwi_Params_init(¶ms);
//FFTIN
// Set the GEM event id in the params
params.eventId = 21;
// Specify the interrupt vector number
intNum = 4;
/* When using CpIntc, you must plug the Hwi fxn with CpIntc_dispatch */
/* so it knows how to process the CpIntc interrupts.*/
Hwi_create(intNum, &CpIntc_dispatch, ¶ms, &eb);
BIOS_start(); /* does not return */
return(0);
]
总结一下中断配置:两核用了相同的中断事件EDMA3CC1 CCINT0 (ps:同一类型的EDMA搬移8核使用相同的edma完成中断事件,不同类型EDMA搬移选择不同edma完成中断事件),即edma中断完成事件,,在CIC0输入为8号事件,通道映射核0输出为32,核1输出为43,对应的GEM event id  都是21,再有INT4输出给CPU,两核有各自的中断服务子程序
希望我的叙述没有让您觉得混乱,期待您的解答
谢谢!
举报

陈小鸥

2018-8-6 09:42:29
引用: huangxie 发表于 2018-8-6 09:32
您好,部分代码如下
//define EDMA3 instances
#define CSL_EDMA3 CSL_EDMA3CC_1

hi,
现多核冲突已经解决,我将上述中断部分代码改写为在非 BIOS 下,发现只能响应一次中断,就是刚上电运行能进入中断,之后再执行EDMA 搬移或者 restart 均无法进入中断。请问这是哪方面原因造成的?还有就是BIOS 下依然无法响应中断,请问BIOS 下我的中断配置是否正确?
谢谢!
举报

杨娟

2018-8-6 10:01:46
引用: huangxie 发表于 2018-8-6 09:42
hi,
现多核冲突已经解决,我将上述中断部分代码改写为在非 BIOS 下,发现只能响应一次中断,就是刚上电运行能进入中断,之后再执行EDMA 搬移或者 restart 均无法进入中断。请问这是哪方面原因造成的?还有就是BIOS 下依然无法响应中断,请问BIOS 下我的中断配置是否正确?
谢谢! ...

Biios及非bios下中断配置参考:http://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices
搬完数据后如果不能产生中断,先check一下相应IPR bit是否置位,如果已经置位,则说明EDMA搬移数据正常,说明与中断配置有关;由于EDMA ISR是路由到CPINTC,在中断响应函数中需要清system event,清IPR bit,然后才能保证响应接下来的中断。
                                                                          

举报

更多回帖

发帖
×
20
完善资料,
赚取积分