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.

MCU-PLUS-SDK-AM263X: Behavior of VIM controller in AM263X in case of nesting same priority

Part Number: MCU-PLUS-SDK-AM263X

I Implement the operating system for a customer.  One of OS features is to enable the user to configure interrupts with any priority  and my OS is responsible for handling these interrupt using VIM controller.
Customer only implement the handler content itself and me as OS developer create the wrapper for this handler.

The design goes like the following (only pseudo code to show the idea):


OS_Wrapper:
B USER_HANDLER
B END_ISR

END_ISR:
clear the interrupt at VIM (clear VIM_STS bit for this source)

And it is expected from the user in his user handler (USER_HANDLER) to clear the interrupt at its source.
So the clearing for interrupt at its source is done first then clearing it at VIM (Interrupt is configured as level interrupt in VIM_INTTYPE)

The problem happens when the exact same interrupt is triggered again during the handling of the first user handler.
Then the sequence will be as follows:

1-User handler is entered and interrupt is cleared at its source.
2-Interrupt comes again and raise the interrupt source again.
3-OS clears VIM flag at END_ISR
4-Now we have interrupt source is 1 and VIM flag is 0. Software stuck forever for this interrupt and never assert VIM flag to 1 again even if the source is kept triggered over and over again.
(The only way to get away from this state is to clear the soucrce explictly and wait for the sourcr to come again)


Expectation:
If interrupt source is 1 then VIM should be 1 again so the interrupt is triggered again (The same interrupt did not get missed if it comes during the handling of the previous handler of the same interrupt) 


  • Hi

    We are looking into this.

    Regards

    Sri Vidya

  • Hi

    Could you please let me know the below details:

    Are you using a custom Interrupt Handler and not the IRQ Handler given by the SDK?

    Are you able to reproduce this issue in the IRQ handler in the SDK?

    clear the interrupt at VIM (clear VIM_STS bit for this source)

    Are you clearing the interrupt based on if the interrupt is level trigger or pulse trigger?

    level trigger --> clear the interrupt after executing the user interrupt and clearing the peripheral interrupt.

    pulse trigger --> clear the interrupt first and then enter the user ISR to clear the peripheral interrupt.

    Thanks & Regards

    Sri Vidya

  • Are you using a custom Interrupt Handler and not the IRQ Handler given by the SDK?

    I am not using Handler given by the SDK.

    Are you able to reproduce this issue in the IRQ handler in the SDK?

    No I did not try the handler in SDK as I should do the handler myself


    Are you clearing the interrupt based on if the interrupt is level trigger or pulse trigger?

    As I mentioned it is a level interrupt and I have followed the datasheet regarding the required sequence 





  • Note: I examined SDK code and it is exactly the same sequence I do

  • The problem happens when the exact same interrupt is triggered again during the handling of the first user handler.

    Are you also using the Hwip_enable and Hwip_disable to allow nesting of the interrupts.

    Is it possible to share your code as I can only verify the nesting from the SDK handler and it is working fine.

    Now we have interrupt source is 1 and VIM flag is 0. Software stuck forever for this interrupt and never assert VIM flag to 1 again even if the source is kept triggered over and over again.

    Could you also specify which interrupt source/peripheral are you using?

    Is the same case happening for both level and pulse trigger interrupts?

    I think you are already aware of the Assembly handler of the SDK:

    In SDK, The interrupt first comes to the Assembly handler and then enters the C handler. For Free Rtos this is present in the file:

    C:\ti\mcu_plus_sdk_am243x_08_05_00_24\source\kernel\freertos\portable\TI_ARM_CLANG\ARM_CR5F\portASM.S.

    API name is HwiP_irq_handler:

    Thanks & regards

    Sri Vidya

  • I cannot share my code but let my explain the situation on SDK code

    void __attribute__((section(".text.hwi"))) HwiP_irq_handler_c(void)
    {
    int32_t status;
    uint32_t intNum;

    #ifndef HWIP_VIM_VIC_ENABLE
    volatile uint32_t gdummy;

    /* Read to force prioritization logic to take effect */
    gdummy = HwiP_getIRQVecAddr();
    #endif

    status = HwiP_getIRQ(&intNum);
    if(status==SystemP_SUCCESS)
    {
    uint32_t isPulse = HwiP_isPulse(intNum);
    HwiP_FxnCallback isr;
    void *args;

    if(isPulse)
    {
    HwiP_clearInt(intNum);
    }

    isr = gHwiCtrl.isr[intNum];
    args = gHwiCtrl.isrArgs[intNum];

    #ifdef HWIP_NESTED_INTERRUPTS_IRQ_ENABLE
    /* allow nesting of interrupts */
    HwiP_enable();
    #endif

    if(isr!=NULL)
    {
    isr(args);
    }

    /* disallow nesting of interrupts */
    HwiP_disable();

    if(!isPulse)
    {
    HwiP_clearInt(intNum);
    }
    HwiP_ackIRQ(intNum);
    }
    else
    {
    /* spurious interrupt */
    gHwiCtrl.spuriousIRQCount++;
    HwiP_ackIRQ(0);
    }
    }

    user handler:

    isr()
    {
    /* Clear interrupt at source */

    /* Same interrupt  comes again here  and interrupt source is raised again */

    }

    Then the sequence is as the following (level interrupt): 
    1-Interrupt is cleared at source in user handler isr()
    2-Interrupt at source is raised again for the same interrupt
    3-HwiP_clearInt() is called and now VIM STS is cleared but Interrupt at source is 1
    4-The stuck happen for this interrupt as mentioned in the description. 


  • Are you also using the Hwip_enable and Hwip_disable to allow nesting of the interrupts ?
    I use something similar but I do not think this is relevant to this issue. 

    Could you also specify which interrupt source/peripheral are you using?
    It is compare match timer interrupt from RTI3.

    Is the same case happening for both level and pulse trigger interrupts?
    Yes I tried to change the interrupt to pulse and the same happens.

     

  • Understood. The sequence seems to be same as SDK.

    Thank you for answering the questions.

    Could you please let me know what is frequency in which you are triggering this RTI Interrupt? I will try to reproduce this with the SDK IRQ handler to better understand the stuck scenario.

    Thanks & Regards

    Sri Vidya

  • Thank you for your follow up

    I do not trigger it with high frequency but simulate it with  busy wait for some time 

    form the user handler you can do something like the following:

    isr()
    {
    /* Clear interrupt at source */

     TRIGGER_INTERRUPT();

    sleep(200000);

    }

    void  sleep ( unsigned int s )
    {
    volatile VAR (uint32, AUTOMATIC) sleepCounter;

    for ( sleepCounter = (uint32) 0U; sleepCounter < (uint32) s ; sleepCounter++ )
    {
    ;
    }
    }

    and at TRIGGER_INTERRUPT you can but a small value in the compare register so it the compare match happens before the sleep function ends 

  • Hi

    Got it. I will try to reproduce at my end please allow me some time.

    Regards

    Sri Vidya

  • Take your time 
    FYI

    I tried to change the interrupt to pulse and it worked (previously when I changed it to pulse I did not change the sequence of when the flags were cleared) 

    So seems this is a bug in level interrupt

    Another important note: 
    We have another project with another target J7 which is cortexR also using the VIM.
    I tried the same sequence on it and I found when VIM is cleared and still interrupt source == 1 it immediately raise the VIM flag again which is expected and which is not happening in VIM of Am263x for interrupts of level type

  • HI

    I tried to change the interrupt to pulse and it worked

    Yes thats what I was thinking to.

    Pulse Interrupt should work.

    So seems this is a bug in level interrupt

    A level interrupt is assumed to be used when there are multiple spurious interrupts for the same interrupt like a GPIO external interrupt.

    So level interrupt is expected to work like this.

    I tried the same sequence on it and I found when VIM is cleared and still interrupt source == 1 it immediately raise the VIM flag again which is expected and which is not happening in VIM of Am263x for interrupts of level type

    Oh I am not aware of J7 IRQ Handler.

    But I will cross check with our SW team if this is expected from our IRQ level interrupt handler.

    Anyway glad you are unblocked.

    Regards

    Sri Vidya

  • So level interrupt is expected to work like this.

    This is different form VIM in J7 as I mentioned.
    And where it is mentioned that this the expected behavior? 

    What I can find in datasheet is exactly the opposite 



    But I will cross check with our SW team if this is expected from our IRQ level interrupt handler.
    Yes please.
  • Hi

    What I can find in datasheet is exactly the opposite 

    Got it. Will pass on this information. 

    Thanks & regards

    sri vidya

  • Hi

    This looks like a timing issue on when the level interrupt is cleared at VIM STS.

    If you clear the STS bit along with the source in your ISR, And then you try to trigger the interrupt again.

    I think this will resolve the issue you are facing for level interrupt.

    Is this what you are expecting?

    Regards

    Sri Vidya

  • I think that I have already explained the bug enough till now and explained it how could it happen in SDK code and I believe that it is really a bug 

    Sorry but I cannot explain over and over again 

  • Hi

    Apologies for the inconvenience caused.

    I will raise a Jira ID for this issue and assign to SW team.

    We will try to fix it in SDK in future releases.

    Thanks & Regards

    Sri Vidya