TI中文支持网
TI专业的中文技术问题搜集分享网站

6678 多核访问EDMA 冲突问题

您好,

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

谢谢!

Allen35065:

使用不同的parameter set,以及中断事件的映射;最好你把两个核上的EDMA配置代码贴出来看看

jack liu_first:

回复 Allen35065:

您好,部分代码如下

//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 failed\n"); return SP_FAIL; }

hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status); if ( (hModule == NULL) || (status != CSL_SOK)) { DEBUG1 ("Edma module open failed\n"); 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,&regionAccess); if (status != CSL_SOK) { DEBUG1("Edma region enable command failed\n"); 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 failed\n"); 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 failed\n"); 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,&regionIntr); if (status != CSL_SOK) { DEBUG1 ("Edma interrupt enable command failed\n"); 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,&regionAccess); if (status != CSL_SOK) { DEBUG1("Edma region enable command failed\n"); 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 failed\n"); 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 failed\n"); 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,&regionIntr); if (status != CSL_SOK) { DEBUG1 ("Edma interrupt enable command failed\n"); return SP_FAIL; }

}

hwSetup.dmaChaSetup = dmahwSetup; hwSetup.qdmaChaSetup = NULL; status = CSL_edma3HwSetup(hModule,&hwSetup); if (status != CSL_SOK) { DEBUG1 ("Hardware setup failed\n"); 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 failed\n"); 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 failed\n"); 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 failed\n"); 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(&params);

//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, &params, &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,两核有各自的中断服务子程序

希望我的叙述没有让您觉得混乱,期待您的解答

谢谢!

jack liu_first:

回复 jack liu_first:

hi,

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

谢谢!

赞(0)
未经允许不得转载:TI中文支持网 » 6678 多核访问EDMA 冲突问题
分享到: 更多 (0)