This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex-M4 interrupts behaviour when same interrupt vector has multiple interrupts

Hello,


I am using STM32F407ZGT6 Cortex-M4 microcontroller. This controller has same interrupt vector for 5 external interrupts i.e., NVIC (EXTI9_5) for EXTI5, EXTI6, EXTI7, EXTI8 and EXTI9 interrupts. They all have the same ISR EXTI9_5_IRQHandler interrupt service routine. So, one has to check the independent flags of each external interrupt to determine the source of the interrupt.

I am confused about how the service routine is called in case multiple interrupts arrived. Lets say, an interrupt due to EXTI5 has arrived, its interrupt handler is called and the interrupt is servicing. Meanwhile, EXTI6 interrupt is detected. Now, will the interrupt handler be called again when the EXTI5 interrupt is fully serviced or since it is already in the interrupt handler, it will not be called again?

In short, which method should I write among the following two styles:

void EXTI9_5_IRQHandler (void)

{

     if EXTI5 happens

     {

          EXTI5 ISR

     }

     if EXTI6 happens

     {

          EXTI6 ISR

     }

     if EXTI7 happens

     {

          EXTI7 ISR

     }

     if EXTI8 happens

     {

          EXTI8 ISR

     }

     if EXTI9 happens

     {

          EXTI9 ISR

     }

}

OR

void EXTI9_5_IRQHandler (void)

{

     if EXTI5 happens

     {

          EXTI5 ISR

     }

     else if EXTI6 happens

     {

          EXTI6 ISR

     }

     else if EXTI7 happens

     {

          EXTI7 ISR

     }

     else if EXTI8 happens

     {

          EXTI8 ISR

     }

     else if EXTI9 happens

     {

          EXTI9 ISR

     }

}

Thanking in anticipation for your time and help.

Parents
  • Just an additional note, in case you want to find out which pin(s) caused the interrupt, you can save the old state in a variable, and then XOR it with the new state...

    ISR {
        static uint32_t oldState = 0;
        uint32_t newState;
        uint32_t changedPins;
    
        newState = /* read_GPIO_Pins here */;
        changedPins = oldState ^ newState;
        oldState = newState;
    
        /* (clear interrupt pending bit here) */
    
        /* now check which pin(s) caused the interrupt: */
        if(changedPins & (1 << 0))
        {
            /* pin 0 was changed */
        }
        if(changedPins & (1 << 1))
        {
            /* pin 1 was changed */
        }
        /* ... etc ... */
    }
    

    You could also use the CLZ instruction from assembly language (inlined assembly), and optionally the REV instruction before that, in order to find the lowest changed pin.

Reply
  • Just an additional note, in case you want to find out which pin(s) caused the interrupt, you can save the old state in a variable, and then XOR it with the new state...

    ISR {
        static uint32_t oldState = 0;
        uint32_t newState;
        uint32_t changedPins;
    
        newState = /* read_GPIO_Pins here */;
        changedPins = oldState ^ newState;
        oldState = newState;
    
        /* (clear interrupt pending bit here) */
    
        /* now check which pin(s) caused the interrupt: */
        if(changedPins & (1 << 0))
        {
            /* pin 0 was changed */
        }
        if(changedPins & (1 << 1))
        {
            /* pin 1 was changed */
        }
        /* ... etc ... */
    }
    

    You could also use the CLZ instruction from assembly language (inlined assembly), and optionally the REV instruction before that, in order to find the lowest changed pin.

Children
No data