portENTER_CRITICAL portEXIT_CRITICAL enables interrupt when it should not.
I am using freertos on stm32g071 devkit and I noticed following problem. Here is a simplified example:
void some_os_api(void)
{
portENTER_CRITICAL();
// do stuff
portEXIT_CRITICAL();
}
void function_call_from_main_or_a_task(void)
{
// save interrupt to restore state after and disable
uint32_t primask = __get_PRIMASK();
__set_PRIMASK(1)
// do something without interruption or task switch
some_os_api();
// do something more here the interrupt should be still disabled, but it is not!
// restore interrupt to what ever it was before
__set_PRIMASK(primask);
}the problem is that portEXIT_CRITICAL does not care if interrupt was already disabled when portENTER_CRITICAL was called. It is obvious from the implementation that is will enable GI in either case which is wrong.
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
portENABLE_INTERRUPTS();
}I know that it must not be called from interrupt context, but this is not the case.
I have not seen any note that interrupt must enabled prior to portEXIT_CRITICAL call. Or did I miss it? If not then it looks like a bug to me.
In my case it breaks the initialization. Because it will enable GI in the middle of the initialization and will execute an interrupt before all memory is initialized. That is obviously a big problem.
Any suggestion how to fix the port macro to behave safely?
