Best practices: How to work with interrupts and low power modes when using the HAL?
NOTE: I have edited this post after some of the replies, to fix some typos in the code and to use "insert code" instead of "Preformated" to get syntax highlighting.
Hello,
I would like to understand what is the recommended approach when working with interrupts and low power modes, when using the HAL.
The approach I'm following right now is:
- Use a volatile variable to indicate if there is an interrupt. One bit for each interrupt.
- Using masking, the corresponding bit is set in each interrupt callback. The callback does not perform any other action.
- In the main infinite loop, go to sleep if there are no interrupts. When woken up, check each bit of the flags variable to serve the pending interrupt(s).
Here is a simplified code sample:
const uint8_t ISR_1 = 0x01;
const uint8_t ISR_2 = 0x02;
const uint8_t ISR_3 = 0x04;
volatile uint8_t isr_flags = 0;
main (){
// Init stuff
while(1){
if (isr_flags == 0){
HAL_SuspendTick(); // Is this call here ok? Could it lead to missing an interrupt?
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();
}
if (isr_flags & ISR_1){
isr_flags &= ~ISR_1;
// do stuff
}
if (isr_flags & ISR_2){
isr_flags &= ~ISR_2;
// do stuff
}
}
}
void HAL_ISR1_Callback(...){
isr_flags |= ISR_1;
}
void HAL_ISR1_Callback(...){
isr_flags |= ISR_2;
}My main questions are:
- Is this the recommended approach by ST when using the HAL?
- Is there a possibility of missing an interrupt due to a race condition?
- From this post https://stackoverflow.com/questions/52784613/which-variable-types-sizes-are-atomic-on-stm32-microcontrollers using an uint8_t should be ok, as the access is atomic, but I'm concerned about HAL_SuspendTick();. What happens if an interrupt arrives and sets the flag while the main is executing that operation? I would then call HAL_PWR_EnterSLEEPMode() and miss an interrupt right? How can I correct this problem or any other that my approach may have?
Thanks and BR
Walter
