feat(freertos/smp): Update ports to support Amazon FreeRTOS v11.0.1

- vTaskPreemptionDisable()/vTaskPreemptionEnable() are no longer available in
single-core builds.
- xTaskIncrementTick() calls must now be wrapped by critical section
- Minimal Idle Task renamed to Passive Idle Task
- Port critical section APIs updated
This commit is contained in:
Darian Leung 2024-02-02 23:37:36 +08:00
parent 888678d102
commit 83c686c744
No known key found for this signature in database
GPG Key ID: 8AC9127B487AA4EF
20 changed files with 148 additions and 135 deletions

View File

@ -6,7 +6,7 @@
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in * this software and associated documentation files (the "Software"), to deal in
@ -110,15 +110,16 @@ BaseType_t xPortCheckIfInISR(void);
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
/* /*
These are always called with interrupts already disabled. We simply need to get/release the spinlocks These are always called with interrupts already disabled. We simply need to get/release the spinlocks
*/ */
extern portMUX_TYPE port_xTaskLock; extern portMUX_TYPE port_xTaskLock;
extern portMUX_TYPE port_xISRLock; extern portMUX_TYPE port_xISRLock;
void vPortTakeLock( portMUX_TYPE *lock ); void vPortTakeLock( portMUX_TYPE *lock );
void vPortReleaseLock( portMUX_TYPE *lock ); void vPortReleaseLock( portMUX_TYPE *lock );
#endif /* configNUMBER_OF_CORES > 1 */
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -151,18 +152,9 @@ void vPortCleanUpTCB ( void *pxTCB );
#define portDISABLE_INTERRUPTS() xPortSetInterruptMask() #define portDISABLE_INTERRUPTS() xPortSetInterruptMask()
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0) #define portENABLE_INTERRUPTS() vPortClearInterruptMask(0)
#define portRESTORE_INTERRUPTS(x) vPortClearInterruptMask(x)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock)
#define portRELEASE_TASK_LOCK() vPortReleaseLock(&port_xTaskLock)
#define portGET_ISR_LOCK() vPortTakeLock(&port_xISRLock)
#define portRELEASE_ISR_LOCK() vPortReleaseLock(&port_xISRLock)
//Critical sections used by FreeRTOS SMP
extern void vTaskEnterCritical( void );
extern void vTaskExitCritical( void );
#define portENTER_CRITICAL_SMP() vTaskEnterCritical(); #define portENTER_CRITICAL_SMP() vTaskEnterCritical();
#define portEXIT_CRITICAL_SMP() vTaskExitCritical(); #define portEXIT_CRITICAL_SMP() vTaskExitCritical();
@ -286,8 +278,8 @@ void vPortExitCriticalIDF(void);
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
// Added for backward compatibility with IDF extern void vPortYield( void );
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI() #define portYIELD() vPortYield()
// ----------------------- System -------------------------- // ----------------------- System --------------------------

View File

@ -298,7 +298,7 @@ void vPortYieldFromISR( void )
xThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); xThreadToSuspend = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
vTaskSwitchContext(xPortGetCoreID()); vTaskSwitchContext();
xThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); xThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );
@ -419,7 +419,7 @@ static void vPortSystemTickHandler( int sig )
#if ( configUSE_PREEMPTION == 1 ) #if ( configUSE_PREEMPTION == 1 )
if (xSwitchRequired == pdTRUE) { if (xSwitchRequired == pdTRUE) {
/* Select Next Task. */ /* Select Next Task. */
vTaskSwitchContext(xPortGetCoreID()); vTaskSwitchContext();
pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); pxThreadToResume = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() );

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -10,15 +10,28 @@
/* Macros used instead ofsetoff() for better performance of interrupt handler */ /* Macros used instead ofsetoff() for better performance of interrupt handler */
#if CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES #if CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES
/*
pxTopOfStack (4) +
xStateListItem (28) +
xEventListItem (28) +
uxPriority (4)
*/
#define PORT_OFFSET_PX_STACK 0x40 #define PORT_OFFSET_PX_STACK 0x40
#else #else
/*
pxTopOfStack (4) +
xStateListItem (20) +
xEventListItem (20) +
uxPriority (4)
*/
#define PORT_OFFSET_PX_STACK 0x30 #define PORT_OFFSET_PX_STACK 0x30
#endif /* #if CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES */ #endif /* #if CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES */
#define PORT_OFFSET_PX_END_OF_STACK (PORT_OFFSET_PX_STACK + \
/* void * pxDummy6 */ 4 + \ #define PORT_OFFSET_PX_END_OF_STACK ( \
/* BaseType_t xDummy23[ 2 ] */ 8 + \ PORT_OFFSET_PX_STACK \
/* uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ] */ CONFIG_FREERTOS_MAX_TASK_NAME_LEN + \ + 4 /* StackType_t * pxStack */ \
/* BaseType_t xDummy24 */ 4) + CONFIG_FREERTOS_MAX_TASK_NAME_LEN /* pcTaskName[ configMAX_TASK_NAME_LEN ] */ \
)
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
@ -102,15 +115,16 @@ BaseType_t xPortCheckIfInISR(void);
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
/* /*
These are always called with interrupts already disabled. We simply need to get/release the spinlocks These are always called with interrupts already disabled. We simply need to get/release the spinlocks
*/ */
extern portMUX_TYPE port_xTaskLock; extern portMUX_TYPE port_xTaskLock;
extern portMUX_TYPE port_xISRLock; extern portMUX_TYPE port_xISRLock;
void vPortTakeLock( portMUX_TYPE *lock ); void vPortTakeLock( portMUX_TYPE *lock );
void vPortReleaseLock( portMUX_TYPE *lock ); void vPortReleaseLock( portMUX_TYPE *lock );
#endif /* configNUMBER_OF_CORES > 1 */
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -175,11 +189,12 @@ void vPortTCBPreDeleteHook( void *pxTCB );
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
#define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock) #define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock)
#define portRELEASE_TASK_LOCK() vPortReleaseLock(&port_xTaskLock) #define portRELEASE_TASK_LOCK() vPortReleaseLock(&port_xTaskLock)
#define portGET_ISR_LOCK() vPortTakeLock(&port_xISRLock) #define portGET_ISR_LOCK() vPortTakeLock(&port_xISRLock)
#define portRELEASE_ISR_LOCK() vPortReleaseLock(&port_xISRLock) #define portRELEASE_ISR_LOCK() vPortReleaseLock(&port_xISRLock)
#endif /* configNUMBER_OF_CORES > 1 */
//Critical sections used by FreeRTOS SMP //Critical sections used by FreeRTOS SMP
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
@ -314,8 +329,8 @@ static inline bool IRAM_ATTR xPortCanYield(void)
return (threshold <= 1); return (threshold <= 1);
} }
// Added for backward compatibility with IDF // Defined even for configNUMBER_OF_CORES > 1 for IDF compatibility
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI() #define portYIELD_WITHIN_API() esp_crosscore_int_send_yield(xPortGetCoreID())
// ----------------------- System -------------------------- // ----------------------- System --------------------------

View File

@ -170,6 +170,7 @@ BaseType_t xPortCheckIfInISR(void)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock ) void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock )
{ {
spinlock_acquire( lock, portMUX_NO_TIMEOUT); spinlock_acquire( lock, portMUX_NO_TIMEOUT);
@ -179,6 +180,7 @@ void IRAM_ATTR vPortReleaseLock( portMUX_TYPE *lock )
{ {
spinlock_release( lock ); spinlock_release( lock );
} }
#endif /* configNUMBER_OF_CORES > 1 */
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -486,21 +488,21 @@ void vApplicationTickHook( void )
#endif #endif
extern void esp_vApplicationIdleHook(void); extern void esp_vApplicationIdleHook(void);
#if CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #if CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK
/* /*
By default, the port uses vApplicationMinimalIdleHook() to run IDF style idle By default, the port uses vApplicationPassiveIdleHook() to run IDF style idle
hooks. However, users may also want to provide their own vApplicationMinimalIdleHook(). hooks. However, users may also want to provide their own vApplicationPassiveIdleHook().
In this case, we use to -Wl,--wrap option to wrap the user provided vApplicationMinimalIdleHook() In this case, we use to -Wl,--wrap option to wrap the user provided vApplicationPassiveIdleHook()
*/ */
extern void __real_vApplicationMinimalIdleHook( void ); extern void __real_vApplicationPassiveIdleHook( void );
void __wrap_vApplicationMinimalIdleHook( void ) void __wrap_vApplicationPassiveIdleHook( void )
{ {
esp_vApplicationIdleHook(); //Run IDF style hooks esp_vApplicationIdleHook(); //Run IDF style hooks
__real_vApplicationMinimalIdleHook(); //Call the user provided vApplicationMinimalIdleHook() __real_vApplicationPassiveIdleHook(); //Call the user provided vApplicationPassiveIdleHook()
} }
#else // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #else // CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK
void vApplicationMinimalIdleHook( void ) void vApplicationPassiveIdleHook( void )
{ {
esp_vApplicationIdleHook(); //Run IDF style hooks esp_vApplicationIdleHook(); //Run IDF style hooks
} }
#endif // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #endif // CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK

View File

@ -7,6 +7,10 @@
#include "portmacro.h" #include "portmacro.h"
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD #if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
#include "esp_private/hw_stack_guard.h" #include "esp_private/hw_stack_guard.h"
#endif
#if CONFIG_FREERTOS_UNICORE
#define pxCurrentTCBs pxCurrentTCB
#endif #endif
.global uxInterruptNesting .global uxInterruptNesting

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -100,15 +100,16 @@ BaseType_t xPortCheckIfInISR(void);
UBaseType_t uxPortEnterCriticalFromISR( void ); UBaseType_t uxPortEnterCriticalFromISR( void );
void vPortExitCriticalFromISR( UBaseType_t level ); void vPortExitCriticalFromISR( UBaseType_t level );
#if ( configNUMBER_OF_CORES > 1 )
/* /*
These are always called with interrupts already disabled. We simply need to get/release the spinlocks These are always called with interrupts already disabled. We simply need to get/release the spinlocks
*/ */
extern portMUX_TYPE port_xTaskLock; extern portMUX_TYPE port_xTaskLock;
extern portMUX_TYPE port_xISRLock; extern portMUX_TYPE port_xISRLock;
void vPortTakeLock( portMUX_TYPE *lock ); void vPortTakeLock( portMUX_TYPE *lock );
void vPortReleaseLock( portMUX_TYPE *lock ); void vPortReleaseLock( portMUX_TYPE *lock );
#endif /* configNUMBER_OF_CORES > 1 */
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -151,35 +152,42 @@ void vPortTCBPreDeleteHook( void *pxTCB );
// --------------------- Interrupts ------------------------ // --------------------- Interrupts ------------------------
#define portDISABLE_INTERRUPTS() ({ \ #define portSET_INTERRUPT_MASK() ({ \
unsigned int prev_level = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); \ unsigned int prev_level = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); \
portbenchmarkINTERRUPT_DISABLE(); \ portbenchmarkINTERRUPT_DISABLE(); \
prev_level = ((prev_level >> XCHAL_PS_INTLEVEL_SHIFT) & XCHAL_PS_INTLEVEL_MASK); \ prev_level = ((prev_level >> XCHAL_PS_INTLEVEL_SHIFT) & XCHAL_PS_INTLEVEL_MASK); \
prev_level; \ prev_level; \
}) })
#define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK()
#define portENABLE_INTERRUPTS() ({ \ #define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
portbenchmarkINTERRUPT_RESTORE(0); \
XTOS_SET_INTLEVEL(0); \
})
/* /*
Note: XTOS_RESTORE_INTLEVEL() will overwrite entire PS register on XEA2. So we need ot make the value INTLEVEL field ourselves Note: XTOS_RESTORE_INTLEVEL() will overwrite entire PS register on XEA2. So we need to set the value of the INTLEVEL field ourselves
*/ */
#define portRESTORE_INTERRUPTS(x) ({ \ #define portCLEAR_INTERRUPT_MASK(x) ({ \
unsigned int ps_reg; \ unsigned int ps_reg; \
RSR(PS, ps_reg); \ RSR(PS, ps_reg); \
ps_reg = (ps_reg & ~XCHAL_PS_INTLEVEL_MASK); \ ps_reg = (ps_reg & ~XCHAL_PS_INTLEVEL_MASK); \
ps_reg |= ((x << XCHAL_PS_INTLEVEL_SHIFT) & XCHAL_PS_INTLEVEL_MASK); \ ps_reg |= ((x << XCHAL_PS_INTLEVEL_SHIFT) & XCHAL_PS_INTLEVEL_MASK); \
XTOS_RESTORE_INTLEVEL(ps_reg); \ XTOS_RESTORE_INTLEVEL(ps_reg); \
}) })
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK(x)
#define portENABLE_INTERRUPTS() ({ \
portbenchmarkINTERRUPT_RESTORE(0); \
XTOS_SET_INTLEVEL(0); \
})
/* Compatibility */
#define portRESTORE_INTERRUPTS(x) portCLEAR_INTERRUPT_MASK(x)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
#define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock) #define portGET_TASK_LOCK() vPortTakeLock(&port_xTaskLock)
#define portRELEASE_TASK_LOCK() vPortReleaseLock(&port_xTaskLock) #define portRELEASE_TASK_LOCK() vPortReleaseLock(&port_xTaskLock)
#define portGET_ISR_LOCK() vPortTakeLock(&port_xISRLock) #define portGET_ISR_LOCK() vPortTakeLock(&port_xISRLock)
#define portRELEASE_ISR_LOCK() vPortReleaseLock(&port_xISRLock) #define portRELEASE_ISR_LOCK() vPortReleaseLock(&port_xISRLock)
#endif /* configNUMBER_OF_CORES > 1 */
//Critical sections used by FreeRTOS SMP //Critical sections used by FreeRTOS SMP
extern void vTaskEnterCritical( void ); extern void vTaskEnterCritical( void );
@ -195,17 +203,10 @@ extern void vTaskExitCritical( void );
#define portEXIT_CRITICAL(...) CHOOSE_MACRO_VA_ARG(portEXIT_CRITICAL_IDF, portEXIT_CRITICAL_SMP, ##__VA_ARGS__)(__VA_ARGS__) #define portEXIT_CRITICAL(...) CHOOSE_MACRO_VA_ARG(portEXIT_CRITICAL_IDF, portEXIT_CRITICAL_SMP, ##__VA_ARGS__)(__VA_ARGS__)
#endif #endif
#define portSET_INTERRUPT_MASK_FROM_ISR() ({ \ extern UBaseType_t vTaskEnterCriticalFromISR( void );
unsigned int cur_level; \ extern void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
RSR(PS, cur_level); \ #define portENTER_CRITICAL_FROM_ISR() vTaskEnterCriticalFromISR()
cur_level = (cur_level & XCHAL_PS_INTLEVEL_MASK) >> XCHAL_PS_INTLEVEL_SHIFT; \ #define portEXIT_CRITICAL_FROM_ISR(x) vTaskExitCriticalFromISR(x)
vTaskEnterCritical(); \
cur_level; \
})
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) ({ \
vTaskExitCritical(); \
portRESTORE_INTERRUPTS(x); \
})
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -356,8 +357,8 @@ static inline bool IRAM_ATTR xPortCanYield(void)
return ((ps_reg & PS_INTLEVEL_MASK) == 0); return ((ps_reg & PS_INTLEVEL_MASK) == 0);
} }
// Added for backward compatibility with IDF // Defined even for configNUMBER_OF_CORES > 1 for IDF compatibility
#define portYIELD_WITHIN_API() vTaskYieldWithinAPI() #define portYIELD_WITHIN_API() esp_crosscore_int_send_yield(xPortGetCoreID())
// ----------------------- System -------------------------- // ----------------------- System --------------------------

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -63,7 +63,7 @@ const DRAM_ATTR uint32_t offset_pxEndOfStack = offsetof(StaticTask_t, pxDummy8);
const DRAM_ATTR uint32_t offset_cpsa = XT_CP_SIZE; /* Offset to start of the CPSA area on the stack. See uxInitialiseStackCPSA(). */ const DRAM_ATTR uint32_t offset_cpsa = XT_CP_SIZE; /* Offset to start of the CPSA area on the stack. See uxInitialiseStackCPSA(). */
#if configNUM_CORES > 1 #if configNUM_CORES > 1
/* Offset to TCB_t.uxCoreAffinityMask member. Used to pin unpinned tasks that use the FPU. */ /* Offset to TCB_t.uxCoreAffinityMask member. Used to pin unpinned tasks that use the FPU. */
const DRAM_ATTR uint32_t offset_uxCoreAffinityMask = offsetof(StaticTask_t, uxDummy25); const DRAM_ATTR uint32_t offset_uxCoreAffinityMask = offsetof(StaticTask_t, uxDummy26);
#if configUSE_CORE_AFFINITY != 1 #if configUSE_CORE_AFFINITY != 1
#error "configUSE_CORE_AFFINITY must be 1 on multicore targets with coprocessor support" #error "configUSE_CORE_AFFINITY must be 1 on multicore targets with coprocessor support"
#endif #endif
@ -72,9 +72,11 @@ const DRAM_ATTR uint32_t offset_uxCoreAffinityMask = offsetof(StaticTask_t, uxDu
volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Indicates whether scheduler is running on a per-core basis volatile unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Indicates whether scheduler is running on a per-core basis
unsigned int port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit unsigned int port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
#if ( configNUMBER_OF_CORES > 1 )
//FreeRTOS SMP Locks //FreeRTOS SMP Locks
portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED; portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED;
#endif /* configNUMBER_OF_CORES > 1 */
/* ------------------------------------------------ IDF Compatibility -------------------------------------------------- /* ------------------------------------------------ IDF Compatibility --------------------------------------------------
* - These need to be defined for IDF to compile * - These need to be defined for IDF to compile
@ -204,6 +206,7 @@ BaseType_t xPortCheckIfInISR(void)
// ------------------ Critical Sections -------------------- // ------------------ Critical Sections --------------------
#if ( configNUMBER_OF_CORES > 1 )
void vPortTakeLock( portMUX_TYPE *lock ) void vPortTakeLock( portMUX_TYPE *lock )
{ {
spinlock_acquire( lock, portMUX_NO_TIMEOUT); spinlock_acquire( lock, portMUX_NO_TIMEOUT);
@ -213,6 +216,7 @@ void vPortReleaseLock( portMUX_TYPE *lock )
{ {
spinlock_release( lock ); spinlock_release( lock );
} }
#endif /* configNUMBER_OF_CORES > 1 */
// ---------------------- Yielding ------------------------- // ---------------------- Yielding -------------------------
@ -262,7 +266,7 @@ static void vPortCleanUpCoprocArea( void *pxTCB )
uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE); uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE);
/* Extract core ID from the affinity mask */ /* Extract core ID from the affinity mask */
xTargetCoreID = ( ( StaticTask_t * ) pxTCB )->uxDummy25 ; xTargetCoreID = ( ( StaticTask_t * ) pxTCB )->uxDummy26;
xTargetCoreID = ( BaseType_t ) __builtin_ffs( ( int ) xTargetCoreID ); xTargetCoreID = ( BaseType_t ) __builtin_ffs( ( int ) xTargetCoreID );
assert( xTargetCoreID >= 1 ); // __builtin_ffs always returns first set index + 1 assert( xTargetCoreID >= 1 ); // __builtin_ffs always returns first set index + 1
xTargetCoreID -= 1; xTargetCoreID -= 1;
@ -667,21 +671,21 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, c
#endif #endif
extern void esp_vApplicationIdleHook(void); extern void esp_vApplicationIdleHook(void);
#if CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #if CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK
/* /*
By default, the port uses vApplicationMinimalIdleHook() to run IDF style idle By default, the port uses vApplicationPassiveIdleHook() to run IDF style idle
hooks. However, users may also want to provide their own vApplicationMinimalIdleHook(). hooks. However, users may also want to provide their own vApplicationPassiveIdleHook().
In this case, we use to -Wl,--wrap option to wrap the user provided vApplicationMinimalIdleHook() In this case, we use to -Wl,--wrap option to wrap the user provided vApplicationPassiveIdleHook()
*/ */
extern void __real_vApplicationMinimalIdleHook( void ); extern void __real_vApplicationPassiveIdleHook( void );
void __wrap_vApplicationMinimalIdleHook( void ) void __wrap_vApplicationPassiveIdleHook( void )
{ {
esp_vApplicationIdleHook(); //Run IDF style hooks esp_vApplicationIdleHook(); //Run IDF style hooks
__real_vApplicationMinimalIdleHook(); //Call the user provided vApplicationMinimalIdleHook() __real_vApplicationPassiveIdleHook(); //Call the user provided vApplicationPassiveIdleHook()
} }
#else // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #else // CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK
void vApplicationMinimalIdleHook( void ) void vApplicationPassiveIdleHook( void )
{ {
esp_vApplicationIdleHook(); //Run IDF style hooks esp_vApplicationIdleHook(); //Run IDF style hooks
} }
#endif // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK #endif // CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK

View File

@ -33,6 +33,10 @@
#define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */ #define TOPOFSTACK_OFFS 0x00 /* StackType_t *pxTopOfStack */
#if CONFIG_FREERTOS_UNICORE
#define pxCurrentTCBs pxCurrentTCB
#endif
.extern pxCurrentTCBs .extern pxCurrentTCBs
#if XCHAL_CP_NUM > 0 #if XCHAL_CP_NUM > 0
/* Offsets used to get a task's coprocessor save area (CPSA) from its TCB */ /* Offsets used to get a task's coprocessor save area (CPSA) from its TCB */

View File

@ -1,20 +1,17 @@
# Overview # Overview
This document outlines some useful notes about This document outlines some notes regarding the Amazon AMP FreeRTOS port in ESP-IDF
- The porting of SMP FreeRTOS to ESP-IDF
- And the difference between IDF FreeRTOS and SMP FreeRTOS
# Terminology # Terminology
The following terms will be used in this document to avoid confusion between the different FreeRTOS versions currently in ESP-IDF The following terms will be used in this document to avoid confusion between the different FreeRTOS versions currently in ESP-IDF
- SMP FreeRTOS: The SMP branch of the FreeRTOS kernel found [here](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp) - SMP FreeRTOS: An SMP capable release of the FreeRTOS kernel described [here](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp)
- IDF FreeRTOS: The version of FreeRTOS used in mainline ESP-IDF that contained custom modifications to support SMP features specific to the ESP chips. - IDF FreeRTOS: The version of FreeRTOS used in mainline ESP-IDF that contained custom modifications to support SMP features specific to the ESP chips.
# Organization # Organization
This directory contains a copy of SMP FreeRTOS based off of upstream commit [8128208](https://github.com/FreeRTOS/FreeRTOS-Kernel/commit/8128208bdee1f997f83cae631b861f36aeea9b1f) This directory contains a copy of upstream [v11.0.1](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/V11.0.1) FreeRTOS which is SMP capable.
- IDF FreeRTOS remains in `components/freertos/FreeRTOS-Kernel` - IDF FreeRTOS remains in `components/freertos/FreeRTOS-Kernel`
- SMP FreeRTOS is entirely contained in `components/freertos/FreeRTOS-Kernel-SMP` - SMP FreeRTOS is entirely contained in `components/freertos/FreeRTOS-Kernel-SMP`
@ -104,15 +101,15 @@ IDF FreeRTOS:
SMP FreeRTOS: SMP FreeRTOS:
- There are now two types of idle task functions. The `prvIdleTask()` and `prvMinimalIdleTask()` - There are now two types of idle task functions. The `prvIdleTask()` and `prvPassiveIdleTask()`
- `prvMinimalIdleTask()` simply calls the `vApplicationMinimalIdleHook()` - `prvPassiveIdleTask()` simply calls the `vApplicationPassiveIdleHook()`
- `prvIdleTask()` calls `prvCheckTasksWaitingTermination()`, `vApplicationIdleHook()`, `vApplicationMinimalIdleHook()`, and handles tickless idle. - `prvIdleTask()` calls `prvCheckTasksWaitingTermination()`, `vApplicationIdleHook()`, `vApplicationPassiveIdleHook()`, and handles tickless idling.
- On an N core build, one `prvIdleTask()` task is created and N-1 `prvMinimalIdleTask()` tasks are created. - On an N core build, one `prvIdleTask()` task is created and N-1 `prvPassiveIdleTask()` tasks are created.
- The created idle tasks are all unpinned. The idle tasks are run on a "first come first serve" basis meaning when a core goes idle, it selects whatever available idle task it can run. - The created idle tasks are all unpinned. The idle tasks are run on a "first come first serve" basis meaning when a core goes idle, it selects whatever available idle task it can run.
Changes Made: Changes Made:
- The `esp_vApplicationIdleHook()` is now called from `vApplicationMinimalIdleHook()` since every idle task calls the `vApplicationMinimalIdleHook()`. - The `esp_vApplicationIdleHook()` is now called from `vApplicationPassiveIdleHook()` since every idle task calls the `vApplicationPassiveIdleHook()`.
- Since the idle tasks are unpinned, the task WDT has been updated to use the "User" feature. Thus, feeding the task watchdog now tracks which "core" has fed the task WDT instead of which specific idle task has fed. - Since the idle tasks are unpinned, the task WDT has been updated to use the "User" feature. Thus, feeding the task watchdog now tracks which "core" has fed the task WDT instead of which specific idle task has fed.
- Since `prvIdleTask()` is solely responsible for calling `prvCheckTasksWaitingTermination()` but can run on any core, multiple IDF cleanup routines are now routed through `portCLEAN_UP_TCB()` - Since `prvIdleTask()` is solely responsible for calling `prvCheckTasksWaitingTermination()` but can run on any core, multiple IDF cleanup routines are now routed through `portCLEAN_UP_TCB()`
- FPU registers of a task are now cleaned up via `portCLEAN_UP_TCB() -> vPortCleanUpCoprocArea()` and can clean FPU save areas across cores. - FPU registers of a task are now cleaned up via `portCLEAN_UP_TCB() -> vPortCleanUpCoprocArea()` and can clean FPU save areas across cores.
@ -169,25 +166,3 @@ IDF FreeRTOS added multiple features/APIs that are specific to IDF. For SMP Free
- If TLSP deletion callbacks are used, `configNUM_THREAD_LOCAL_STORAGE_POINTERS` will be doubled (in order to store the callback pointers in the same array as the TLSPs themselves) - If TLSP deletion callbacks are used, `configNUM_THREAD_LOCAL_STORAGE_POINTERS` will be doubled (in order to store the callback pointers in the same array as the TLSPs themselves)
- `vTaskSetThreadLocalStoragePointerAndDelCallback()` moved to `freertos_tasks_c_additions.h`/`idf_additions.h` - `vTaskSetThreadLocalStoragePointerAndDelCallback()` moved to `freertos_tasks_c_additions.h`/`idf_additions.h`
- Deletion callbacks invoked from the main idle task via `portCLEAN_UP_TCB()` - Deletion callbacks invoked from the main idle task via `portCLEAN_UP_TCB()`
### `xTaskGetCurrentTaskHandleForCPU()`
- Convenience function to the get current task of a particular CPU
- Moved to `freertos_tasks_c_additions.h`/`idf_additions.h` for now
Todo: Check if this can be upstreamed
### `xTaskGetIdleTaskHandleForCPU()`
- Currently moved to `freertos_tasks_c_additions.h`/`idf_additions.h`
Todo: This needs to be deprecated as there is no longer the concept of idle tasks pinned to a particular CPU
### `xTaskGetAffinity()`
- Returns what core a task is pinned to, and not the task's affinity mask.
- Moved to `freertos_tasks_c_additions.h`/`idf_additions.h` and simple wraps `vTaskCoreAffinityGet()`
- If the task's affinity mask has more than one permissible core, we simply return `tskNO_AFFINITY` even if the task is not completely unpinned.
Todo: This needs to be deprecated and users should call `vTaskCoreAffinityGet()` instead

View File

@ -3,6 +3,7 @@ menu "FreeRTOS"
menu "Kernel" menu "Kernel"
# Upstream FreeRTOS configurations go here # Upstream FreeRTOS configurations go here
config FREERTOS_SMP config FREERTOS_SMP
bool "Run the Amazon SMP FreeRTOS kernel instead (FEATURE UNDER DEVELOPMENT)" bool "Run the Amazon SMP FreeRTOS kernel instead (FEATURE UNDER DEVELOPMENT)"
depends on !IDF_TARGET_ESP32P4 #TODO: IDF-8113: Enable P4 support on AMZ SMP depends on !IDF_TARGET_ESP32P4 #TODO: IDF-8113: Enable P4 support on AMZ SMP
@ -116,7 +117,7 @@ menu "FreeRTOS"
- The FreeRTOS idle hook is NOT the same as the ESP-IDF Idle Hook, but both can be enabled - The FreeRTOS idle hook is NOT the same as the ESP-IDF Idle Hook, but both can be enabled
simultaneously. simultaneously.
config FREERTOS_USE_MINIMAL_IDLE_HOOK config FREERTOS_USE_PASSIVE_IDLE_HOOK
bool "Use FreeRTOS minimal idle hook" bool "Use FreeRTOS minimal idle hook"
depends on FREERTOS_SMP depends on FREERTOS_SMP
default n default n
@ -126,8 +127,8 @@ menu "FreeRTOS"
Note: Note:
- The application must provide the hook function ``void vApplicationMinimalIdleHook( void );`` - The application must provide the hook function ``void vApplicationPassiveIdleHook( void );``
- ``vApplicationMinimalIdleHook()`` is called from FreeRTOS minimal idle task(s) - ``vApplicationPassiveIdleHook()`` is called from FreeRTOS minimal idle task(s)
config FREERTOS_USE_TICK_HOOK config FREERTOS_USE_TICK_HOOK
bool "configUSE_TICK_HOOK" bool "configUSE_TICK_HOOK"

View File

@ -262,10 +262,11 @@
* - All Amazon SMP FreeRTOS specific configurations * - All Amazon SMP FreeRTOS specific configurations
* ------------------------------------------------------------------------------------------------------------------ */ * ------------------------------------------------------------------------------------------------------------------ */
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP && ( CONFIG_FREERTOS_NUMBER_OF_CORES > 1 )
#define configUSE_CORE_AFFINITY 1
#define configRUN_MULTIPLE_PRIORITIES 1 #define configRUN_MULTIPLE_PRIORITIES 1
#define configUSE_TASK_PREEMPTION_DISABLE 1 #define configUSE_TASK_PREEMPTION_DISABLE 1
#endif /* CONFIG_FREERTOS_SMP */ #endif /* CONFIG_FREERTOS_SMP && ( CONFIG_FREERTOS_NUMBER_OF_CORES > 1 ) */
/* -------------------------------------------------- IDF FreeRTOS ----------------------------------------------------- /* -------------------------------------------------- IDF FreeRTOS -----------------------------------------------------
* - All IDF FreeRTOS specific configurations * - All IDF FreeRTOS specific configurations
@ -290,4 +291,4 @@
/* portNUM_PROCESSORS is deprecated and will be removed in ESP-IDF v6.0 (IDF-8785) /* portNUM_PROCESSORS is deprecated and will be removed in ESP-IDF v6.0 (IDF-8785)
* Please use the Kconfig option CONFIG_FREERTOS_NUMBER_OF_CORES instead. * Please use the Kconfig option CONFIG_FREERTOS_NUMBER_OF_CORES instead.
*/ */
#define portNUM_PROCESSORS configNUMBER_OF_CORES #define portNUM_PROCESSORS configNUMBER_OF_CORES

View File

@ -31,7 +31,7 @@
/* ---------------- Amazon SMP FreeRTOS -------------------- */ /* ---------------- Amazon SMP FreeRTOS -------------------- */
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP
#define configUSE_MINIMAL_IDLE_HOOK 0 /* Not implemented yet, TODO IDF-6654 */ #define configUSE_PASSIVE_IDLE_HOOK 0 /* Not implemented yet, TODO IDF-6654 */
#endif #endif
/* ----------------------- System -------------------------- */ /* ----------------------- System -------------------------- */

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -27,15 +27,10 @@
/* ---------------- Amazon SMP FreeRTOS -------------------- */ /* ---------------- Amazon SMP FreeRTOS -------------------- */
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP
#define configUSE_CORE_AFFINITY 1
/* This is always enabled to call IDF style idle hooks, by can be "--Wl,--wrap" /* This is always enabled to call IDF style idle hooks, by can be "--Wl,--wrap"
* if users enable CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK. */ * if users enable CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK. */
#define configUSE_MINIMAL_IDLE_HOOK 1 #define configUSE_PASSIVE_IDLE_HOOK 1
/* IDF Newlib supports dynamic reentrancy. We provide our own __getreent()
* function. */
#define configNEWLIB_REENTRANT_IS_DYNAMIC 1
#endif #endif
/* ----------------------- System -------------------------- */ /* ----------------------- System -------------------------- */
@ -46,9 +41,13 @@
* - We simply provide our own INIT and DEINIT functions * - We simply provide our own INIT and DEINIT functions
* - We set "SET" to a blank macro since there is no need to set the reentrancy * - We set "SET" to a blank macro since there is no need to set the reentrancy
* pointer. All newlib functions calls __getreent. */ * pointer. All newlib functions calls __getreent. */
#define configINIT_TLS_BLOCK( xTLSBlock ) esp_reent_init( &( xTLSBlock ) ) #if CONFIG_FREERTOS_SMP
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) esp_reent_init( &( xTLSBlock ) )
#else /* CONFIG_FREERTOS_SMP */
#define configINIT_TLS_BLOCK( xTLSBlock ) esp_reent_init( &( xTLSBlock ) )
#endif /* CONFIG_FREERTOS_SMP */
#define configSET_TLS_BLOCK( xTLSBlock ) #define configSET_TLS_BLOCK( xTLSBlock )
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -54,15 +54,10 @@
/* ---------------- Amazon SMP FreeRTOS -------------------- */ /* ---------------- Amazon SMP FreeRTOS -------------------- */
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP
#define configUSE_CORE_AFFINITY 1
/* This is always enabled to call IDF style idle hooks, by can be "--Wl,--wrap" /* This is always enabled to call IDF style idle hooks, by can be "--Wl,--wrap"
* if users enable CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK. */ * if users enable CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK. */
#define configUSE_MINIMAL_IDLE_HOOK 1 #define configUSE_PASSIVE_IDLE_HOOK 1
/* IDF Newlib supports dynamic reentrancy. We provide our own __getreent()
* function. */
#define configNEWLIB_REENTRANT_IS_DYNAMIC 1
#endif #endif
/* ----------------------- System -------------------------- */ /* ----------------------- System -------------------------- */
@ -73,9 +68,13 @@
* - We simply provide our own INIT and DEINIT functions * - We simply provide our own INIT and DEINIT functions
* - We set "SET" to a blank macro since there is no need to set the reentrancy * - We set "SET" to a blank macro since there is no need to set the reentrancy
* pointer. All newlib functions calls __getreent. */ * pointer. All newlib functions calls __getreent. */
#define configINIT_TLS_BLOCK( xTLSBlock ) esp_reent_init( &( xTLSBlock ) ) #if CONFIG_FREERTOS_SMP
#define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) esp_reent_init( &( xTLSBlock ) )
#else /* CONFIG_FREERTOS_SMP */
#define configINIT_TLS_BLOCK( xTLSBlock ) esp_reent_init( &( xTLSBlock ) )
#endif /* CONFIG_FREERTOS_SMP */
#define configSET_TLS_BLOCK( xTLSBlock ) #define configSET_TLS_BLOCK( xTLSBlock )
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1

View File

@ -29,7 +29,9 @@
*/ */
_Static_assert( offsetof( StaticTask_t, pxDummy6 ) == offsetof( TCB_t, pxStack ) ); _Static_assert( offsetof( StaticTask_t, pxDummy6 ) == offsetof( TCB_t, pxStack ) );
_Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfStack ) ); _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfStack ) );
#if !CONFIG_IDF_TARGET_LINUX // Disabled for linux builds due to differences in types
_Static_assert( tskNO_AFFINITY == ( BaseType_t ) CONFIG_FREERTOS_NO_AFFINITY, "CONFIG_FREERTOS_NO_AFFINITY must be the same as tskNO_AFFINITY" ); _Static_assert( tskNO_AFFINITY == ( BaseType_t ) CONFIG_FREERTOS_NO_AFFINITY, "CONFIG_FREERTOS_NO_AFFINITY must be the same as tskNO_AFFINITY" );
#endif
/* ------------------------------------------------- Kernel Control ------------------------------------------------- */ /* ------------------------------------------------- Kernel Control ------------------------------------------------- */

View File

@ -88,6 +88,8 @@ entries:
port_common (noflash_text) # Default all functions to internal RAM port_common (noflash_text) # Default all functions to internal RAM
if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y: if FREERTOS_PLACE_FUNCTIONS_INTO_FLASH = y:
port_common:vApplicationGetIdleTaskMemory (default) port_common:vApplicationGetIdleTaskMemory (default)
if FREERTOS_SMP = y && FREERTOS_UNICORE = n:
port_common:vApplicationGetPassiveIdleTaskMemory (default)
port_common:vApplicationGetTimerTaskMemory (default) port_common:vApplicationGetTimerTaskMemory (default)
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------

View File

@ -57,6 +57,16 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
} }
#if ( ( CONFIG_FREERTOS_SMP ) && ( configNUMBER_OF_CORES > 1 ) )
void vApplicationGetPassiveIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize,
BaseType_t xPassiveIdleTaskIndex)
{
vApplicationGetIdleTaskMemory(ppxIdleTaskTCBBuffer, ppxIdleTaskStackBuffer, pulIdleTaskStackSize);
}
#endif /* ( ( CONFIG_FREERTOS_SMP ) && ( configNUMBER_OF_CORES > 1 ) ) */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer, StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize) uint32_t *pulTimerTaskStackSize)

View File

@ -201,6 +201,7 @@ BaseType_t xPortSysTickHandler(void)
// Call FreeRTOS Increment tick function // Call FreeRTOS Increment tick function
BaseType_t xSwitchRequired; BaseType_t xSwitchRequired;
#if CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_SMP
UBaseType_t uxSavedStatus = taskENTER_CRITICAL_FROM_ISR();
// Amazon SMP FreeRTOS requires that only core 0 calls xTaskIncrementTick() // Amazon SMP FreeRTOS requires that only core 0 calls xTaskIncrementTick()
#if ( configNUM_CORES > 1 ) #if ( configNUM_CORES > 1 )
if (portGET_CORE_ID() == 0) { if (portGET_CORE_ID() == 0) {
@ -211,6 +212,7 @@ BaseType_t xPortSysTickHandler(void)
#else /* configNUM_CORES > 1 */ #else /* configNUM_CORES > 1 */
xSwitchRequired = xTaskIncrementTick(); xSwitchRequired = xTaskIncrementTick();
#endif /* configNUM_CORES > 1 */ #endif /* configNUM_CORES > 1 */
taskEXIT_CRITICAL_FROM_ISR(uxSavedStatus);
#else /* !CONFIG_FREERTOS_SMP */ #else /* !CONFIG_FREERTOS_SMP */
#if ( configNUM_CORES > 1 ) #if ( configNUM_CORES > 1 )
/* /*

View File

@ -109,7 +109,7 @@ Expected:
static void unpinned_task(void *arg) static void unpinned_task(void *arg)
{ {
// Disable scheduling/preemption to make sure the current task doesn't switch cores // Disable scheduling/preemption to make sure the current task doesn't switch cores
#if CONFIG_FREERTOS_SMP #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
vTaskPreemptionDisable(NULL); vTaskPreemptionDisable(NULL);
#else #else
vTaskSuspendAll(); vTaskSuspendAll();
@ -140,7 +140,7 @@ static void unpinned_task(void *arg)
#endif #endif
#endif // !CONFIG_FREERTOS_UNICORE #endif // !CONFIG_FREERTOS_UNICORE
// Reenable scheduling/preemption // Reenable scheduling/preemption
#if CONFIG_FREERTOS_SMP #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
vTaskPreemptionEnable(NULL); vTaskPreemptionEnable(NULL);
#else #else
xTaskResumeAll(); xTaskResumeAll();

View File

@ -130,7 +130,7 @@ Expected:
static void unpinned_task(void *arg) static void unpinned_task(void *arg)
{ {
// Disable scheduling/preemption to make sure current core ID doesn't change // Disable scheduling/preemption to make sure current core ID doesn't change
#if CONFIG_FREERTOS_SMP #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
vTaskPreemptionDisable(NULL); vTaskPreemptionDisable(NULL);
#else #else
vTaskSuspendAll(); vTaskSuspendAll();
@ -166,7 +166,7 @@ static void unpinned_task(void *arg)
#endif #endif
#endif // !CONFIG_FREERTOS_UNICORE #endif // !CONFIG_FREERTOS_UNICORE
// Reenable scheduling/preemption // Reenable scheduling/preemption
#if CONFIG_FREERTOS_SMP #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) )
vTaskPreemptionEnable(NULL); vTaskPreemptionEnable(NULL);
#else #else
xTaskResumeAll(); xTaskResumeAll();