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

ISRs, flags and enables question (STM32)

I'm using a USB stack (libusb_stm32) on an STM32F103 for learning.  In this stack, when data arrives from the host PC, a callback in the USB ISR** runs a function of mine to put the data into my queue.  In this function of mine I have disabled interrupts, but I do NOT think I need to. Is this a correct assumption?

What surprises me here, is that old_primask is 0. Maybe I'm confused, but I expected in an ISR it would be 1. It does become 1 once __disable_irq() runs.

void Enqueue_Callback(uint8_t bytefromhost)
{
uint32_t old_primask;         // don't need? VECTACTIVE is 0x24

old_primask = __get_PRIMASK(); // don't need? old primask was 0x0000 0000
__disable_irq();               // don't need? primask becomes 0x0000 0001

myenqueue(bytefromhost);      // I have shared vars in here (counter).

__set_PRIMASK( old_primask ); // don't need?
}

On the flip side I believe that I DO need to disable interrupts so that the USB interrupt can't interfere with my dequeueing. Is that correct? Here is that side:

bool Dequeue(uint8_t *ch_ptr)
{
uint32_t old_primask;           // VECTACTIVE is 0x00

old_primask = __get_PRIMASK();  // old primask is 0x0000 0000
__disable_irq();                // becomes 0x0000 0001

if( thereisdata() )             // <pseudocode>
   {
   mydequeue(ch_ptr);         // I have shared vars in here (count).

   __set_PRIMASK( old_primask );
   return 0;
   }

__set_PRIMASK( old_primask );
return 1;
}

** I verified that the callback happens at ISR level using this:

// Q. How to safely detect if a function is called from an ISR?
// A. You need to test the VECTACTIVE field of the Interrupt Control State Register.

inline bool isInterrupt(void)
{
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0 ;
}

Parents
  •  In this function of mine I have disabled interrupts, but I do NOT think I need to. Is this a correct assumption?

    You will need to make the final decision here, but nothing that is running at Thread Mode can execute while you in Handler Mode.  As long as your dequeue is only happening in thread mode then you do not need to disable interrupts in the USB handler.

    What surprises me here, is that old_primask is 0. Maybe I'm confused, but I expected in an ISR it would be 1. It does become 1 once __disable_irq() runs.

    primask is something set and cleared my software.  It is not modified by the hardware based on the interrupt state.  so

    1) if the software has not set the Primask to 1, the Primask value will not be 1.

    2) if the software sets the Primask to 0, the Primask value will be 0

    3) The test of the Primask is used so that the original state (set or cleared) is restored when the section is left. If it was set on entry, you want it to remain set on exit.  if it was not set on entry, you want it to go back to not set on exit.

    On the flip side I believe that I DO need to disable interrupts so that the USB interrupt can't interfere with my dequeueing. Is that correct? 

    If there is a possibility of the USB IRQ being called while you are dequing the data then yes, you will need to do some form of disabling that interrup while you dequeue the items.

Reply
  •  In this function of mine I have disabled interrupts, but I do NOT think I need to. Is this a correct assumption?

    You will need to make the final decision here, but nothing that is running at Thread Mode can execute while you in Handler Mode.  As long as your dequeue is only happening in thread mode then you do not need to disable interrupts in the USB handler.

    What surprises me here, is that old_primask is 0. Maybe I'm confused, but I expected in an ISR it would be 1. It does become 1 once __disable_irq() runs.

    primask is something set and cleared my software.  It is not modified by the hardware based on the interrupt state.  so

    1) if the software has not set the Primask to 1, the Primask value will not be 1.

    2) if the software sets the Primask to 0, the Primask value will be 0

    3) The test of the Primask is used so that the original state (set or cleared) is restored when the section is left. If it was set on entry, you want it to remain set on exit.  if it was not set on entry, you want it to go back to not set on exit.

    On the flip side I believe that I DO need to disable interrupts so that the USB interrupt can't interfere with my dequeueing. Is that correct? 

    If there is a possibility of the USB IRQ being called while you are dequing the data then yes, you will need to do some form of disabling that interrup while you dequeue the items.

Children