程序使用了BIOS,SRIO和timer都使用的是CSL配置的中断,但是在把SRIO和timer程加到使用MessageQ Module的BIOS程序中程序跑到MessageQ_open就无法继续跑下去,但是使用的SRIO和timer程序在不使用messageQ module的BIOS程序中自己能够调通,对于遇到得这个问题,我应该怎么办?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
程序使用了BIOS,SRIO和timer都使用的是CSL配置的中断,但是在把SRIO和timer程加到使用MessageQ Module的BIOS程序中程序跑到MessageQ_open就无法继续跑下去,但是使用的SRIO和timer程序在不使用messageQ module的BIOS程序中自己能够调通,对于遇到得这个问题,我应该怎么办?
使用的芯片是6670,SYS/BIOS 使用的是6.34.2.18
这是timer配置中断的部分的程序。
/* Perform Interrupt initialisation if required */
if( g_TimerMode == BSLC667X_TIMER_INTERRUPT_MODE )
{
/* Ensure that INTC module is initialised and is available */
if(IntcInitialise(NULL))
return BSLC667X_INTC_ERROR;
/* Plug TIMER(4 or 8) interrupt */
/* Route TIMER(4 or 8) lower counter event to CPU interrupt 15 */
vectId = (CSL_IntcVectId) BSLC667X_TIMERX_LO_IVT_PRI;
/* Open handle for INTC - for use to
* install TIMER(4 or 8) event dispatcher
*/
hIntc = CSL_intcOpen (&intcTimerObj, 0x42, (CSL_IntcParam*)&vectId , &status);
/* Validate opened handle */
if ( (hIntc == NULL) || (status != CSL_SOK) )
{
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
/* Use independent timer handler */
status |= CSL_intcHookIsr(vectId,TimerInterruptHandler);
/* Enable timer event */
status |= CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTENABLE,NULL);
/* IF error, return */
if (status != CSL_SOK)
{
/* Close CSL interrupt handle */
CSL_intcClose(hIntc);
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
}
函数 IntcInitialise的代码
BSLC667X_ErrorCode IntcInitialise (
BSLC667X_IntcUserConfObj_s *pBSLC667X_IntcUserConf )
{
static Int32 siBSLC667X_IntcInitialised = FALSE;
CSL_Status status;
if (!siBSLC667X_IntcInitialised)
{
/* Initialize INTC module of CSL library */
g_IntcContext_my.eventhandlerRecord = g_EvtObj_my;
g_IntcContext_my.numEvtEntries = BSLC667X_INTC_NUM_EVT_ENTRY;
if( (status = CSL_intcInit(&g_IntcContext_my)) != CSL_SOK)
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
/* Enable NMIs */
if( (status = CSL_intcGlobalNmiEnable()) != CSL_SOK )
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
/* Enable Global interrupts */
if( (status = CSL_intcGlobalEnable(&g_uiGlobalEnableState_my)) != CSL_SOK )
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
/* Initialise CPU interrupt table flag */
// g_usCpuIntrTableFlag=0xFFF3;
/* Mark all 4 interrupt combiner ISRs as unplugged */
g_ucBSLC667X_IntcCombinerResource_my = 0xF;
/* Set intc module(s) as available */
g_uiBSLC667X_IntcResource_my = 0x01;
_CSL_intcCpuIntrTable.isr4 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr5 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr6 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr7 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr8 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr9 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr10 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr11 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr12 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr13 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr14 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr15 = _CSL_intcNmiDummy;
/* Clean Interrupt */
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[0]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[1]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[2]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[3]=0xFFFFFFFF;
/* Unmask All combiner events */
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTMASK[0]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTMASK[1]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTMASK[2]=0xFFFFFFFF;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTMASK[3]=0xFFFFFFFF;
/* Clear all interrupt mux registers */
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX1=0x0B0B0B0B;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX2=0x0B0B0B0B;
((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX3=0x0B0B0B0B;
/* INTC is now initialised */
siBSLC667X_IntcInitialised = TRUE;
}
return (BSLC667X_INTC_OK);
}
SRIO的配置中断的代码
if( pSrioUserConfObj->SrioModeIntrPollDriven == BSLC667X_SRIO_INTERRUPT_MODE )
{
/* Ensure that INTC module is initialised and is available */
if( Err = IntcInitialise(NULL) )
return Err;
/*
* Configure Interrupt Module
*/
if(!siIntcEventMap)
{
/* SRIO sys events and channel(host intr) mapping*/
Uint8 Sys_Events[] = BSLC667X_INTC0_SRIO_SYS_INTR;
#ifdef c6670
Uint8 Host_Channels[] = BSLC6670_INTC0_SRIO_HOST_INTR;
#else
Uint8 Host_Channels[] = BSLC6678_INTC0_SRIO_HOST_INTR;
#endif
/** CPINTC handle for INTC0 */
cpIntc = CSL_CPINTC_open(CSL_CP_INTC_0);
if((void*)cpIntc == NULL)
{
return BSLC667X_SRIO_ERROR;
}
/* Nesting mode of INTC0 */
CSL_CPINTC_disableAllHostInterrupt(cpIntc);
CSL_CPINTC_setNestingMode(cpIntc, CPINTC_NO_NESTING);
/* Enable the system SRIO interrupt */
for(i = 0; i< (sizeof(Sys_Events)/sizeof(Sys_Events[0])); i++)
{
/*System to Host interrupt Mapping*/
CSL_CPINTC_mapSystemIntrToChannel(cpIntc, Sys_Events[i], Host_Channels[i]);
/*Enable System Interrupt*/
CSL_CPINTC_enableSysInterrupt(cpIntc, Sys_Events[i]);
/* Enable the channel (output). */
CSL_CPINTC_enableHostInterrupt(cpIntc,Host_Channels[i]);
}
/* Enable all host interrupts. */
CSL_CPINTC_enableAllHostInterrupt(cpIntc);
/* CPINTC interrupts initialised*/
siIntcEventMap = TRUE;
}
/* Plug Srio interrupt */
if( !siBSLC667X_RioInt )
{
/* Route Srio Interrupt 0 event to BSLC667X_ defined SRIO LSU CPU interrupt */
vectId = (CSL_IntcVectId) BSLC667X_SRIO_LSU_IVT_PRI;
/* Open handle for INTC - for use to
* install Srio Interrupt 0 event dispatcher
*/
hIntc = CSL_intcOpen (&intcSrioObj, BSLC667X_GEM_INTC0_SRIO_LSU_INTR, (CSL_IntcParam*)&vectId , &status);/*CSL_GEM_INTC0_OUT_8_PLUS_16_MUL_N*/
/* Validate opened handle */
if ( (hIntc == NULL) || (status != CSL_SOK) )
{
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
/* Use independent srio handler */
status |= CSL_intcHookIsr(vectId,BSLC667X_SrioLsuInterruptHandler);
/* Enable Srio Interrupt 0 event */
if( (status |= CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTENABLE,NULL)) != CSL_SOK )
{
/* Close CSL interrupt handle */
CSL_intcClose(hIntc);
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
/* Mark RIO 0 interrupt as plugged */
siBSLC667X_RioInt = TRUE;
}
if( !siBSLC667X_RioDBInt )
{
/* Route Srio Interrupt 1 event to CPU interrupt 10 */
vectId = (CSL_IntcVectId) BSLC667X_SRIO_DOORBELL_IVT_PRI;
/* Open handle for INTC - for use to
* install Srio Interrupt 1 event dispatcher
*/
hIntc = CSL_intcOpen (&intcSrioObj, CSL_GEM_INTDST_N_PLUS_16 , (CSL_IntcParam*)&vectId , &status);
/* Validate opened handle */
if ( (hIntc == NULL) || (status != CSL_SOK) )
{
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
/* Use independent srio handler */
status |= CSL_intcHookIsr(vectId,BSLC667X_SrioDoorBellIntrHandler);
/* Enable Srio Interrupt 1 event */
if( (status |= CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTENABLE,NULL)) != CSL_SOK )
{
/* Close CSL interrupt handle */
CSL_intcClose(hIntc);
return BSLC667X_TICSL_TO_BSLC667X_ERR_MAKE(status);
}
/* Mark RIO 1 interrupt as plugged */
siBSLC667X_RioDBInt = TRUE;
}
}
Hocodrecon,
注意到Timer相关部分使用了如下代码:
_CSL_intcCpuIntrTable.isr4 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr5 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr6 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr7 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr8 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr9 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr10 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr11 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr12 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr13 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr14 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr15 = _CSL_intcNmiDummy;
该代码重置了中断的配置。 请打开BOIS的配置文件,看一下默认使用了哪些中断,更改Timer代码中相应的中断不去覆盖BOIS使用的资源。
cgf文件中的配置如下,其他和中断相关的就没有了。
var ECM = xdc.useModule ("ti.sysbios.family.c64p.EventCombiner");
var C64_Hwi = xdc.useModule ("ti.sysbios.family.c64p.Hwi");
var CpIntc = xdc.useModule('ti.sysbios.family.c66.tci66xx.CpIntc');
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
ECM.eventGroupHwiNum[0] = 7;
ECM.eventGroupHwiNum[1] = 8;
ECM.eventGroupHwiNum[2] = 9;
ECM.eventGroupHwiNum[3] = 10;
timer使用的是interrupt 9
我把
_CSL_intcCpuIntrTable.isr7 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr8 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr9 = _CSL_intcNmiDummy;
_CSL_intcCpuIntrTable.isr10 = _CSL_intcNmiDummy;
注释掉了,还是不行,
其他程序也是上边的配置,但没有使用MesssageQ 就没有问题。
timer的程序相对简单一些,我把它改成用SYS/BIOS的方式
修改后的代码如下:
Hwi_Params hwiParams;
Error_Block eb;
Hwi_Handle myHwi;
Hwi_Params_init(&hwiParams);
Error_init(&eb);
// set the argument you want passed to your ISR function
hwiParams.arg = 1;
// set the event id of the peripheral assigned to this interrupt
hwiParams.eventId = 0x42;
/* Enable the Hwi */
hwiParams.enableInt = TRUE;
// don't allow this interrupt to nest itself
hwiParams.maskSetting = Hwi_MaskingOption_SELF;
myHwi = Hwi_create(11, TimerInterruptHandler, &hwiParams, &eb);
麻烦看一下对不对,
最开始使用的vectorID9,而不是11,结果是如下
[C66xx_0] ti.sysbios.family.c64p.Hwi: line 159: E_alreadyDefined: Hwi already defined: intr# 9
ti.sysbios.family.c64p.Hwi: line 234: E_handleNotFound: Hwi handle not found: 0x89c6e8
xdc.runtime.Error.raise: terminating execution
后来才改成11 的,是不是因为ECM.eventGroupHwiNum[2] = 9;所以就不能用了呢?
但是改成11之后,timer的用中断的方式可以实现,但是程序继续往下进行就成了下边的样子
A22=0xc000100a A23=0x297854
A24=0x32602048 A25=0x4c
A26=0x8bcbc4 A27=0x8bcbc4
A28=0x8bcbc4 A29=0x800
A30=0x8bc1ac A31=0x0
B0=0x1 B1=0x8bc1b0
B2=0x0 B3=0x0
B4=0x8bc164 B5=0x4fa3
B6=0x8919e0 B7=0x0
B8=0x0 B9=0x0
B10=0x4fa3 B11=0x8944c0
B12=0x0 B13=0x800
B14=0x8bc1f0 B15=0x8bc258
B16=0x0 B17=0x0
B18=0xf00 B19=0x40
B20=0x0 B21=0x100
B22=0x400f B23=0x0
B24=0x8b9b04 B25=0xf15f6284
B26=0x558e301 B27=0x8806340
B28=0xc8900100 B29=0x48
B30=0x8bc204 B31=0x0
NTSR=0x1000f
ITSR=0x400f
IRP=0x8919e0
SSR=0x0
AMR=0x0
RILC=0x0
ILC=0x0
Exception at 0x0
EFR=0x2 NRP=0x0
Internal exception: IERR=0x1
Instruction fetch exception
ti.sysbios.family.c64p.Exception: line 248: E_exceptionMin: pc = 0x00000000, sp = 0x008bc258.
To see more exception detail, use ROV or set 'ti.sysbios.family.c64p.Exception.enablePrint = true;'
xdc.runtime.Error.raise: terminating execution
这又是怎么回事呢?
我看到的程序上 eventID 使用函数Cpintc_getEvent得到的,我这里是直接用 用CSL方式配置的eventsID,什么时候应该用前边的函数得到呢?
hocodrecon,
从打印信息上来看,代码PC指针跑到0x0地址了。 NRP=0x0指示异常代码PC地址为0地址。
错误是进入TIMER中断之后马上产生的吗? 能单步跟一下为何进入0地址?
void test_timer(void)
{
#if TIMETEST1
timer_ini();
#endif
timer_str timer;
#if TIMETEST2
int abc;
BSLC667X_ErrorCode Err;
timer.uiMicroSec = 5000000;
Err = TimerMicrosecWait (&timer);
if(Err)
flag = 0;//printf("BSLC667X_TimerMicrosecWait() failed!!, ErrorCode = 0x%x\n",Err);
else
flag = 1;//printf("BSLC667X_TimerMicrosecWait 5 seconds SUCCESS ...\n");
//查询定时时间
if(g_TimerMode != BSLC667X_TIMER_POLLING_MODE)
{
while( !g_viIntCount1 )
{
// printf("%d\n",timer.hTmr->regs->CNTLO);
}
timer.pg_viIntCount1 = 0;
}
else
{
abc = timer.uiMicroSec * BSLC667X_TIMERX_EXT_INPUT_FREQ -50;
while ( !(timer.hTmr->regs->CNTLO > abc));
}
timer_colse(&timer);
#endif
}
就是在跳出该函数的时候出现上边的情况的
Hocodrecon,
从出错的打印来看, B3=0,通常B3是作为函数的返回地址。 如果推断正确的话,这个函数的返回地址是0而不是它的调用函数。
请在这个函数的入口处打断点,用反汇编模式查看进入函数时的B3值是多少,再在函数的末尾打断点,单步跟踪到B3出栈后的值是否与前面的值一致。 我估计是在这个函数中,B3在堆栈中的值被改写了。
void test_timer(void)
{
#if TIMETEST1
timer_ini();
#endif
timer_str timer;
#if TIMETEST2
int abc;
BSLC667X_ErrorCode Err;
timer.uiMicroSec = 5000000;
Err = TimerMicrosecWait (&timer);
if(Err)
flag = 0;//printf("BSLC667X_TimerMicrosecWait() failed!!, ErrorCode = 0x%x\n",Err);
else
flag = 1;//printf("BSLC667X_TimerMicrosecWait 5 seconds SUCCESS ...\n");
//查询定时时间
if(g_TimerMode != BSLC667X_TIMER_POLLING_MODE)
{
while( !g_viIntCount1 )
{
// printf("%d\n",timer.hTmr->regs->CNTLO);
}
timer.pg_viIntCount1 = 0;
}
else
{
abc = timer.uiMicroSec * BSLC667X_TIMERX_EXT_INPUT_FREQ -50;
while ( !(timer.hTmr->regs->CNTLO > abc));
}
// timer_colse(&timer);
#endif
}
进入函数前的值为0x00878e4,进入函数之后为0x00858eb8,跑完timer_ini()后,有变为了0x008918ec,TimerMicrosecWait之后变为0x00877088
跑到最后的时候
反汇编到 BNOP.S2 B3,5
B3的值就变成了0x0.
根据前面的信息,B15=0x8bc258, 根据上述汇编信息,可以推断 B15[42] 的地址为0x8bc258.
B3的值是从0x8bc258处取出来的。 你可以对照查一下这个地址的值是否为0. 如果是正常的情况,B15[42]地址的内容是函数返回地址,也就是调用test_timer()指令的下一条语句的地址,不会为0.
重点查堆栈的这段memory是否在执行这个函数的时候被改写。
Jane Lu 谢谢你的回答,我看了其他地方的程序,将中断调用的函数 由
interrupt void TimerInterruptHandler( void )
{
g_viIntCount1=1;
/* Disable Interrupts and Save Previous Interrupt Enable State */
asm(" dint");
/* Clear timer event */
CSL_intcEventClear((CSL_IntcEventId)0x42);
/* Restore Previous Interrupt Enable State */
asm(" rint");
}
改成了
static void TimerInterruptHandler2 (void *arg)
{
/* Increment the number of interrupts detected. */
g_viIntCount1=1;
/* Clear the event ID. */
CSL_intcEventClear((CSL_IntcEventId)arg);
}
之后,并修改HWI的配置中的相应的参数后没有在出现上边的情况,现在情况和原来的一样了,程序也是到messageQ_Open 就跑不下去了。
那么,这个问题该怎么办呢?
同时我还想再问两个问题
1.以上两种中断调用函数有什么区别,有什么地方有介绍吗?
2.还有就是寄存器A和B中各个寄存器的含义和作用可以去哪里看看呢?
Hocodrecon,
关于interrupt关键字的作用在编译器的文档spru187中有介绍。 文档里面有说明,bois的中断处理函数不能使用interrupt关键字。
关于在函数调用过程中各个寄存器的含义和作用也请看这篇文档的“Function Structure and Calling Conventions”章节。
关于messageQ引起的问题,请问程序跑不下去的具体现象是什么?