GCC CM4F port :

Hello,

on the FAQHelp page:

  1. My application crashes before the RTOS scheduler is even started
    A context switch cannot occur until after the RTOS scheduler has started. Any interrupt service routine that could potentially cause a context switch must therefore not be permitted to execute prior to the RTOS scheduler being started. The same is true of any interrupt service routine that attempts to send to or receive from a queue or semaphore.Many API functions cannot be called prior to the RTOS scheduler being started. It is best to restrict such usage to the creation of the tasks, queues and semaphores that will be used once the RTOS scheduler activity has commenced.

on STM32 cm4F.

In the initialization function of my app (before the scheduler is started, I create some synchronization objects. Let’s talk about xEventGroupCreate().

xEventGroupCreate() leads to this call stack:

image

at the end, vPortExitCritical() is called.

Here are their implementations:

void vPortEnterCritical( void )
{
	portDISABLE_INTERRUPTS();
	uxCriticalNesting++;

	/* This is not the interrupt safe version of the enter critical function so
	assert() if it is being called from an interrupt context.  Only API
	functions that end in "FromISR" can be used in an interrupt.  Only assert if
	the critical nesting count is 1 to protect against recursive calls if the
	assert function also uses a critical section. */
	if( uxCriticalNesting == 1 )
	{
		configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
	}
}
/*-----------------------------------------------------------*/

void vPortExitCritical( void )
{
	configASSERT( uxCriticalNesting );
	uxCriticalNesting--;
	if( uxCriticalNesting == 0 )
	{
		portENABLE_INTERRUPTS();
	}
}

uxCriticalNesting is initialized like this:

static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;

and set to 0 when scheculer starts.
Based on this behaviour, a call to xEventGroupCreate() will disable interrupts and not re-enable them on exit if scheduler is not started.

Sa news, some other features of the app called after eventGroup creation require a call to delay function relying on SysTick. Of course this does not work because all interrupts are disabled.

Crawling the code, I did not understand while uxCriticalNesting is not initialized to 0 but there should be a good reason.

So my question is: what’s the good way to overcome this issue?

Thanks
Julien

This behavior is intentional to ensure that the ISRs do not start calling FreeRTOS APIs before the scheduler is started.

Are you using some other timer to drive FreeRTOS tick? If so, you should set the priority of SysTick higher (numerically lower) than configMAX_SYSCALL_INTERRUPT_PRIORITY assuming that you do not call any FreeRTOS API from the SysTick handler.

My best solution is to move the code that needs to use delays into a Task that is run after the scheduler is started.

ok, thanks to you two!