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.

MessageQ Module 和SRIO ,timer中断方式的的程序不能和在一起?

Other Parts Discussed in Thread: SYSBIOS

程序使用了BIOS,SRIO和timer都使用的是CSL配置的中断,但是在把SRIO和timer程加到使用MessageQ Module的BIOS程序中程序跑到MessageQ_open就无法继续跑下去,但是使用的SRIO和timer程序在不使用messageQ module的BIOS程序中自己能够调通,对于遇到得这个问题,我应该怎么办?

  • Hocodrecon,

                  建议检查一下MessageQ open需要使用的资源是否和SRIO有冲突。 另外,timer也需要检查是否和BIOS默认使用的timer是否存在冲突。

                  另外,BOIS管理的中断资源和CSL管理中断是否冲突?

  • 加上timer 或者SRIO之后,中断的方式是可以成功的,但是MessageQ open 不能用。这样的话BIOS管理的中断资源应该与CSL库的没有冲突吧。

    对于检查MessageQ open需要使用的资源是否和SRIO有冲突,麻烦你说的具体一些。

  • 请粘贴一下出错部分代码以及使用的芯片信息,BOIS版本号,谢谢!

  • 使用的芯片是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使用的资源。

  • intc的中断管理和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引起的问题,请问程序跑不下去的具体现象是什么?

  • 跑到messageQ_open就成了running

  • 在中断函数中要不要加    asm(" dint")  和   asm(" rint")?

  • 可以加,也可以不加,取决于您自己的软件系统设计。

  • 麻烦问一下,你用message Q 实现2个核通信是怎么实现的呢?能否给我代码看看

  • 你建CCS工程的时候直接建IPC的工程就行了,你也可以看看IPC的手册,里面有说IPC的程序怎么建,你看看就知道怎么多核通信了。

  • 能否留一个邮箱、qq联系方式?谢谢了