硬件平台C6678
软件ccs5.3,mcsdk最新。
我有这样一个需求,将硬件信号量和本地信号量结合使用,以实现当任务没有获取信号量时可以放弃cpu进行等待状态,当硬件信号量被释放时,此任务又可被唤醒。
封装接口,在信号量创建时分配一个bios的信号量和硬件信号量结合起来。当获取硬件信号量没有成功时,会调用bios的信号量的pend接口实现阻塞,当硬件信号量被其他core释放后,本core或收到一个0x10号的中断,在中断处理中对BIOS的信号量进行释放,这样就可以唤醒被信号量阻塞的任务。
我在初始化intc的时候,挂载的都是0x10好中断0xC号事件。测试用例中每个core不断的回去同一个信号量,并且等待1000tick后对信号量进行释放。
运行的结果是:在硬件信号量第一次被获取并释放后,其他core获取任务没有被唤醒。我个人觉得是中断挂载的不正确。
请问,中断和事件是怎么使用的,在使用信号量中断时要注意什么?
附上中断初始化代码:
static Uint32 configInterrupt (CSL_IntcEventHandler isr, CSL_IntcParam vectId, CSL_IntcEventId eventId)
{
/************************************************
****************** INTC Configuration **************** ************************************************/
printf("Core %d Debug: INTC initialization start …\n", DNUM);
/* INTC module initialization */
intcContext.eventhandlerRecord = EventHandler;
intcContext.numEvtEntries = 10;
if (CSL_intcInit(&intcContext) != CSL_SOK) {
printf("Core %d Error: GEM-INTC initialization failed\n", DNUM);
return -1;
}
/* Enable NMIs */
if (CSL_intcGlobalNmiEnable() != CSL_SOK) {
printf("Core %d Error: GEM-INTC global NMI enable failed\n", DNUM);
return -1;
}
/* Enable global interrupts */
if ((intStat = CSL_intcGlobalEnable(&state)) != CSL_SOK) {
printf ("Core %d Error: GEM-INTC global enable failed\n", DNUM);
return -1;
}
/* Open the INTC Module for Vector ID and Event ID *Refer to the interrupt architecture and mapping document for the Event ID */
hnd = CSL_intcOpen (&intcObj, eventId, &vectId, &intStat);
if (hnd == NULL) {
printf("Core %d Error: GEM-INTC Open failed\n", DNUM);
return -1;
}
/* Register an call-back handler which is invoked when the event occurs. */
EventRecord.handler = isr;
EventRecord.arg = (void *)vectId;
if (CSL_intcPlugEventHandler(hnd,&EventRecord) != CSL_SOK) {
printf("Core %d Error: GEM-INTC Plug event handler failed\n", DNUM);
return -1;
}
/* Clear the before event */
if (CSL_intcHwControl(hnd, CSL_INTC_CMD_EVTCLEAR, NULL) != CSL_SOK) {
printf("Core %d Error: GEM-INTC CSL_INTC_CMD_EVTCLEAR command failed\n", DNUM);
return -1;
}
/* Enable the event */
if (CSL_intcHwControl(hnd, CSL_INTC_CMD_EVTENABLE, NULL) != CSL_SOK) {
printf("Core %d Error: GEM-INTC CSL_INTC_CMD_EVTENABLE command failed\n", DNUM);
return -1;
}
printf("Core %d Debug: INTC initialization finished …\n", DNUM);
return 0;
}
以及中断处理代码:
static void interruptISR ()
{
flag = CSL_semGetFlags(DNUM); //determine the granted semaphore
CSL_semClearFlags(DNUM, flag);
CSL_semSetEoi(DNUM); //reenable the SEMINTn to the specific core
/**************************************************************/
/* Disable the interrupts. */ CSL_intcHwControl(intcHandle, CSL_INTC_CMD_EVTDISABLE, NULL);
/* Close the Interrupt Handles. */
CSL_intcClose(intcHandle);
/*post local sem,resume the waited task*/
Semaphore_post(localsem)
}
每个core都调用下面的语句进行初始化
result = configInterrupt((CSL_IntcEventHandler)&interruptISR, (CSL_IntcParam)0xC, (CSL_IntcEventId)0x10);
请帮忙看一下,上面的代码有什么问题么?
Andy Yin1:
参考hardware semaphore例程:http://www.deyisupport.com/question_answer/dsp_arm/c6000_multicore/f/53/t/4899.aspx
在bios工程中不可以用csl配置core INTC并注册中断服务函数,参考中断控制器的配置:http://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices
yu mo:
回复 Andy Yin1:
你好,谢谢你的回复,我写的代码就是参照你给的例子写的。能不能提供一个使用bios的hwi来设置硬件信号量中断的例子?谢谢。