FreeRTOS / FreeRTOS-Kernel

FreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.

Home Page:https://www.FreeRTOS.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Will timer task be created twice for smp x2 freertos

fanghuaqi opened this issue · comments

According to the source code here

FreeRTOS-Kernel/timers.c

Lines 294 to 301 in 067d04e

vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &uxTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
uxTimerTaskStackSize,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
pxTimerTaskStackBuffer,
pxTimerTaskTCBBuffer );

When configNUMBER_OF_CORES = 1 and configUSE_CORE_AFFINITY = 0, it will go to above lines, and this xTimerCreateTimerTask function will be call in each cpu via vTaskStartScheduler called from main.

FreeRTOS-Kernel/tasks.c

Lines 3665 to 3690 in 067d04e

void vTaskStartScheduler( void )
{
BaseType_t xReturn;
traceENTER_vTaskStartScheduler();
#if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 )
{
/* Sanity check that the UBaseType_t must have greater than or equal to
* the number of bits as confNUMBER_OF_CORES. */
configASSERT( ( sizeof( UBaseType_t ) * taskBITS_PER_BYTE ) >= configNUMBER_OF_CORES );
}
#endif /* #if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 ) */
xReturn = prvCreateIdleTasks();
#if ( configUSE_TIMERS == 1 )
{
if( xReturn == pdPASS )
{
xReturn = xTimerCreateTimerTask();
}
else
{
mtCOVERAGE_TEST_MARKER();
}

But it seems it doesn't create different stack for different cpu's timer task like the idle task, is it made on intent?

Thanks

I checked other porting code, found that only main core need to execute main function, which including task creating and vTaskStartScheduler, other cores should only execute xPortStartScheduler and some other code to initialize required core interrupt controller.

BaseType_t xPortStartScheduler( void )
{
configASSERT( ucPrimaryCoreNum == INVALID_PRIMARY_CORE_NUM );
/* No one else should use these! */
spin_lock_claim( configSMP_SPINLOCK_0 );
spin_lock_claim( configSMP_SPINLOCK_1 );
#if portRUNNING_ON_BOTH_CORES
ucPrimaryCoreNum = configTICK_CORE;
configASSERT( get_core_num() == 0 ); /* we must be started on core 0 */
multicore_launch_core1( prvDisableInterruptsAndPortStartSchedulerOnCore );
#else
ucPrimaryCoreNum = get_core_num();
#endif
xPortStartSchedulerOnCore();
/* Should not get here! */
return 0;
}
#else /* if ( configNUMBER_OF_CORES > 1 ) */