diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h index 2e36eb17b0..8a4e681e48 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h @@ -3279,6 +3279,15 @@ void vTaskYieldWithinAPI( void ); #ifdef ESP_PLATFORM +#if ( configNUM_CORES > 1 ) +/* +Workaround for non-thread safe multi-core OS startup (see IDF-4524) +This function must be called with interrupts disabled on all cores other than +core 0 during startup. +*/ +void vTaskStartSchedulerOtherCores( void ); +#endif // configNUM_CORES > 1 + #include "idf_additions.h" #endif //ESP_PLATFORM diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 08a1cc6d2c..bbd091efe5 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -448,6 +448,13 @@ BaseType_t xPortStartScheduler( void ) port_xSchedulerRunning[xPortGetCoreID()] = 1; +#if configNUM_CORES > 1 + // Workaround for non-thread safe multi-core OS startup (see IDF-4524) + if (xPortGetCoreID() != 0) { + vTaskStartSchedulerOtherCores(); + } +#endif // configNUM_CORES > 1 + // Cannot be directly called from C; never returns __asm__ volatile ("call0 _frxt_dispatch\n"); diff --git a/components/freertos/FreeRTOS-Kernel-SMP/tasks.c b/components/freertos/FreeRTOS-Kernel-SMP/tasks.c index 6aa7a506fe..18d1f9570b 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/tasks.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/tasks.c @@ -369,7 +369,15 @@ PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tas PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; +#if ( ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1 ) ) +/* +Workaround for non-thread safe multi-core OS startup (see IDF-4524) +*/ +PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunningPerCore[ configNUM_CORES ] = { pdFALSE }; +#define xSchedulerRunning xSchedulerRunningPerCore[ portGET_CORE_ID() ] +#else // ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1 ) PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +#endif // ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1 ) PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U; PRIVILEGED_DATA static volatile BaseType_t xYieldPendings[ configNUM_CORES ] = { pdFALSE }; PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; @@ -6443,3 +6451,14 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, #endif #endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */ + +#if ( ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1 ) ) +/* +Workaround for non-thread safe multi-core OS startup (see IDF-4524) +*/ +void vTaskStartSchedulerOtherCores( void ) +{ + /* This function is always called with interrupts disabled*/ + xSchedulerRunning = pdTRUE; +} +#endif // ( ESP_PLATFORM == 1 ) && ( configNUM_CORES > 1