mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
change(freertos): Deprecate usage of vPortCleanUpTCB() by applications
Previously, if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP was enabled, users would provide a definition for a vPortCleanUpTCB() hook function that is called right before a task's memory is freed in prvDeleteTCB(). However, vPortCleanUpTCB() will be reclaimed by ESP-IDF for internal use in v6.0. This commit introduces the following changes... Introduced a new CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK option: - Provides the same pre-deletion hook functionality. But users now define vTaskPreDeletionHook() instead. - CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP still exists, but is marked as deprecated. This is to maintain compatibility with existing applications that already define vPortCleanUpTCB(). - Removed redundant --wl --wrap workaround with vPortCleanUpTCB() - Added todo notes to remove support for user defined vPortCleanUpTCB() completely in v6.0. - Updated test cases to use new CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK option Freed up portCLEAN_UP_TCB() to call a new internal vPortTCBPreDeleteHook(): - vPortTCBPreDeleteHook() now replaces the previous "wrapped" implementation of vPortCleanUpTCB(). - vPortTCBPreDeleteHook() is an internal task pre-delete hook for IDF FreeRTOS ports to inject some pre-deletion operations. - Internal pre-delete hook now invokes user provided vTaskPreDeletionHook() if enabled. - Relocated vPortTCBPreDeleteHook() to correct section in port.c
This commit is contained in:
parent
9d8b121ef2
commit
39cf3638ae
@ -250,7 +250,4 @@ else()
|
||||
idf_component_optional_requires(PRIVATE esp_pm)
|
||||
endif()
|
||||
|
||||
if(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP AND CONFIG_FREERTOS_SMP)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=vPortCleanUpTCB")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -143,9 +143,19 @@ void vPortYieldFromISR(void);
|
||||
|
||||
static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void );
|
||||
|
||||
// ----------------------- TCB Cleanup --------------------------
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
void vPortCleanUpTCB ( void *pxTCB );
|
||||
/**
|
||||
* @brief TCB cleanup hook
|
||||
*
|
||||
* The portCLEAN_UP_TCB() macro is called in prvDeleteTCB() right before a
|
||||
* deleted task's memory is freed. We map that macro to this internal function
|
||||
* so that IDF FreeRTOS ports can inject some task pre-deletion operations.
|
||||
*
|
||||
* @note We can't use vPortCleanUpTCB() due to API compatibility issues. See
|
||||
* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP. Todo: IDF-8097
|
||||
*/
|
||||
void vPortTCBPreDeleteHook( void *pxTCB );
|
||||
|
||||
/* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
|
||||
* - Contains all the mappings of the macros required by FreeRTOS
|
||||
@ -218,7 +228,8 @@ extern void vTaskExitCritical( void );
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB )
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortTCBPreDeleteHook( pxTCB )
|
||||
|
||||
|
||||
/* --------------------------------------------- Inline Implementations ------------------------------------------------
|
||||
* - Implementation of inline functions of the forward declares
|
||||
|
@ -208,6 +208,63 @@ void vPortYieldFromISR( void )
|
||||
uxSchedulerRunning = 1;
|
||||
xPortSwitchFlag = 1;
|
||||
}
|
||||
// ----------------------- System --------------------------
|
||||
|
||||
// ------------------- Run Time Stats ----------------------
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
static void vPortTLSPointersDelCb( void *pxTCB )
|
||||
{
|
||||
/* Typecast pxTCB to StaticTask_t type to access TCB struct members.
|
||||
* pvDummy15 corresponds to pvThreadLocalStoragePointers member of the TCB.
|
||||
*/
|
||||
StaticTask_t *tcb = ( StaticTask_t * )pxTCB;
|
||||
|
||||
/* The TLSP deletion callbacks are stored at an offset of (configNUM_THREAD_LOCAL_STORAGE_POINTERS/2) */
|
||||
TlsDeleteCallbackFunction_t *pvThreadLocalStoragePointersDelCallback = ( TlsDeleteCallbackFunction_t * )( &( tcb->pvDummy15[ ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ] ) );
|
||||
|
||||
/* We need to iterate over half the depth of the pvThreadLocalStoragePointers area
|
||||
* to access all TLS pointers and their respective TLS deletion callbacks.
|
||||
*/
|
||||
for ( int x = 0; x < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ); x++ ) {
|
||||
if ( pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) { //If del cb is set
|
||||
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||
ESP_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||
abort();
|
||||
}
|
||||
|
||||
pvThreadLocalStoragePointersDelCallback[ x ]( x, tcb->pvDummy15[ x ] ); //Call del cb
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
void vPortTCBPreDeleteHook( void *pxTCB )
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK )
|
||||
/* Call the user defined task pre-deletion hook */
|
||||
extern void vTaskPreDeletionHook( void * pxTCB );
|
||||
vTaskPreDeletionHook( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK */
|
||||
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/*
|
||||
* If the user is using the legacy task pre-deletion hook, call it.
|
||||
* Todo: Will be removed in IDF-8097
|
||||
*/
|
||||
#warning "CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is deprecated. Use CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK instead."
|
||||
extern void vPortCleanUpTCB( void * pxTCB );
|
||||
vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
/* Call TLS pointers deletion callbacks */
|
||||
vPortTLSPointersDelCb( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------ FreeRTOS Portable --------------------------------------------------
|
||||
* - Provides implementation for functions required by FreeRTOS
|
||||
@ -423,36 +480,6 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
|
||||
//TODO: IDF-2393
|
||||
}
|
||||
|
||||
// ------- Thread Local Storage Pointers Deletion Callbacks -------
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
void vPortTLSPointersDelCb( void *pxTCB )
|
||||
{
|
||||
/* Typecast pxTCB to StaticTask_t type to access TCB struct members.
|
||||
* pvDummy15 corresponds to pvThreadLocalStoragePointers member of the TCB.
|
||||
*/
|
||||
StaticTask_t *tcb = ( StaticTask_t * )pxTCB;
|
||||
|
||||
/* The TLSP deletion callbacks are stored at an offset of (configNUM_THREAD_LOCAL_STORAGE_POINTERS/2) */
|
||||
TlsDeleteCallbackFunction_t *pvThreadLocalStoragePointersDelCallback = ( TlsDeleteCallbackFunction_t * )( &( tcb->pvDummy15[ ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ] ) );
|
||||
|
||||
/* We need to iterate over half the depth of the pvThreadLocalStoragePointers area
|
||||
* to access all TLS pointers and their respective TLS deletion callbacks.
|
||||
*/
|
||||
for ( int x = 0; x < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ); x++ ) {
|
||||
if ( pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) { //If del cb is set
|
||||
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||
ESP_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||
abort();
|
||||
}
|
||||
|
||||
pvThreadLocalStoragePointersDelCallback[ x ]( x, tcb->pvDummy15[ x ] ); //Call del cb
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||
|
||||
// ------------------- Hook Functions ----------------------
|
||||
|
||||
void __attribute__((weak)) vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
|
||||
@ -496,26 +523,3 @@ void vApplicationMinimalIdleHook( void )
|
||||
esp_vApplicationIdleHook(); //Run IDF style hooks
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK
|
||||
|
||||
/*
|
||||
* Hook function called during prvDeleteTCB() to cleanup any
|
||||
* user defined static memory areas in the TCB.
|
||||
*/
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
void __real_vPortCleanUpTCB( void *pxTCB );
|
||||
|
||||
void __wrap_vPortCleanUpTCB( void *pxTCB )
|
||||
#else
|
||||
void vPortCleanUpTCB ( void *pxTCB )
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/* Call user defined vPortCleanUpTCB */
|
||||
__real_vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
/* Call TLS pointers deletion callbacks */
|
||||
vPortTLSPointersDelCb( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
}
|
||||
|
@ -127,9 +127,20 @@ static inline void __attribute__((always_inline)) vPortYieldFromISR( void );
|
||||
|
||||
static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void );
|
||||
|
||||
// ----------------------- TCB Cleanup --------------------------
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
/**
|
||||
* @brief TCB cleanup hook
|
||||
*
|
||||
* The portCLEAN_UP_TCB() macro is called in prvDeleteTCB() right before a
|
||||
* deleted task's memory is freed. We map that macro to this internal function
|
||||
* so that IDF FreeRTOS ports can inject some task pre-deletion operations.
|
||||
*
|
||||
* @note We can't use vPortCleanUpTCB() due to API compatibility issues. See
|
||||
* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP. Todo: IDF-8097
|
||||
*/
|
||||
void vPortTCBPreDeleteHook( void *pxTCB );
|
||||
|
||||
void vPortCleanUpTCB ( void *pxTCB );
|
||||
|
||||
/* ----------------------------------------- FreeRTOS SMP Porting Interface --------------------------------------------
|
||||
* - Contains all the mappings of the macros required by FreeRTOS SMP
|
||||
@ -221,9 +232,9 @@ extern void vTaskExitCritical( void );
|
||||
#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) ({x = (uint32_t)esp_timer_get_time();})
|
||||
#endif
|
||||
|
||||
// ------------------- TCB Cleanup ----------------------
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB )
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortTCBPreDeleteHook( pxTCB )
|
||||
|
||||
/* --------------------------------------------- Inline Implementations ------------------------------------------------
|
||||
* - Implementation of inline functions of the forward declares
|
||||
|
@ -42,6 +42,14 @@
|
||||
|
||||
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
|
||||
|
||||
/**
|
||||
* @brief Align stack pointer in a downward growing stack
|
||||
*
|
||||
* This macro is used to round a stack pointer downwards to the nearest n-byte boundary, where n is a power of 2.
|
||||
* This macro is generally used when allocating aligned areas on a downward growing stack.
|
||||
*/
|
||||
#define STACKPTR_ALIGN_DOWN(n, ptr) ((ptr) & (~((n)-1)))
|
||||
|
||||
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
||||
* - Various variables used to maintain the FreeRTOS port's state. Used from both port.c and various .S files
|
||||
* - Constant offsets are used by assembly to jump to particular TCB members or a stack area (such as the CPSA). We use
|
||||
@ -209,6 +217,90 @@ void vPortReleaseLock( portMUX_TYPE *lock )
|
||||
|
||||
// ----------------------- System --------------------------
|
||||
|
||||
// ------------------- Run Time Stats ----------------------
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
static void vPortTLSPointersDelCb( void *pxTCB )
|
||||
{
|
||||
/* Typecast pxTCB to StaticTask_t type to access TCB struct members.
|
||||
* pvDummy15 corresponds to pvThreadLocalStoragePointers member of the TCB.
|
||||
*/
|
||||
StaticTask_t *tcb = ( StaticTask_t * )pxTCB;
|
||||
|
||||
/* The TLSP deletion callbacks are stored at an offset of (configNUM_THREAD_LOCAL_STORAGE_POINTERS/2) */
|
||||
TlsDeleteCallbackFunction_t *pvThreadLocalStoragePointersDelCallback = ( TlsDeleteCallbackFunction_t * )( &( tcb->pvDummy15[ ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ] ) );
|
||||
|
||||
/* We need to iterate over half the depth of the pvThreadLocalStoragePointers area
|
||||
* to access all TLS pointers and their respective TLS deletion callbacks.
|
||||
*/
|
||||
for ( int x = 0; x < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ); x++ ) {
|
||||
if ( pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) { //If del cb is set
|
||||
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||
// We call EARLY log here as currently portCLEAN_UP_TCB() is called in a critical section
|
||||
ESP_EARLY_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||
abort();
|
||||
}
|
||||
|
||||
pvThreadLocalStoragePointersDelCallback[ x ]( x, tcb->pvDummy15[ x ] ); //Call del cb
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
#if ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
static void vPortCleanUpCoprocArea( void *pxTCB )
|
||||
{
|
||||
UBaseType_t uxCoprocArea;
|
||||
BaseType_t xTargetCoreID;
|
||||
|
||||
/* Get pointer to the task's coprocessor save area from TCB->pxEndOfStack. See uxInitialiseStackCPSA() */
|
||||
uxCoprocArea = ( UBaseType_t ) ( ( ( StaticTask_t * ) pxTCB )->pxDummy8 ); /* Get TCB_t.pxEndOfStack */
|
||||
uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE);
|
||||
|
||||
/* Extract core ID from the affinity mask */
|
||||
xTargetCoreID = ( ( StaticTask_t * ) pxTCB )->uxDummy25 ;
|
||||
xTargetCoreID = ( BaseType_t ) __builtin_ffs( ( int ) xTargetCoreID );
|
||||
assert( xTargetCoreID >= 1 ); // __builtin_ffs always returns first set index + 1
|
||||
xTargetCoreID -= 1;
|
||||
|
||||
/* If task has live floating point registers somewhere, release them */
|
||||
void _xt_coproc_release(volatile void *coproc_sa_base, BaseType_t xTargetCoreID);
|
||||
_xt_coproc_release( (void *)uxCoprocArea, xTargetCoreID );
|
||||
}
|
||||
#endif /* ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 ) */
|
||||
|
||||
void vPortTCBPreDeleteHook( void *pxTCB )
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK )
|
||||
/* Call the user defined task pre-deletion hook */
|
||||
extern void vTaskPreDeletionHook( void * pxTCB );
|
||||
vTaskPreDeletionHook( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK */
|
||||
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/*
|
||||
* If the user is using the legacy task pre-deletion hook, call it.
|
||||
* Todo: Will be removed in IDF-8097
|
||||
*/
|
||||
#warning "CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is deprecated. Use CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK instead."
|
||||
extern void vPortCleanUpTCB( void * pxTCB );
|
||||
vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
/* Call TLS pointers deletion callbacks */
|
||||
vPortTLSPointersDelCb( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
#if ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
/* Cleanup coproc save area */
|
||||
vPortCleanUpCoprocArea( pxTCB );
|
||||
#endif /* ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 ) */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------ FreeRTOS Portable --------------------------------------------------
|
||||
* - Provides implementation for functions required by FreeRTOS
|
||||
* - Declared in portable.h
|
||||
@ -269,14 +361,6 @@ static void vPortTaskWrapper(TaskFunction_t pxCode, void *pvParameters)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Align stack pointer in a downward growing stack
|
||||
*
|
||||
* This macro is used to round a stack pointer downwards to the nearest n-byte boundary, where n is a power of 2.
|
||||
* This macro is generally used when allocating aligned areas on a downward growing stack.
|
||||
*/
|
||||
#define STACKPTR_ALIGN_DOWN(n, ptr) ((ptr) & (~((n)-1)))
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
/**
|
||||
* @brief Allocate and initialize coprocessor save area on the stack
|
||||
@ -559,61 +643,6 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||
// Return the task's current stack pointer address which should point to the starting interrupt stack frame
|
||||
return (StackType_t *)uxStackPointer;
|
||||
}
|
||||
// -------------------- Co-Processor -----------------------
|
||||
#if ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
|
||||
void _xt_coproc_release(volatile void *coproc_sa_base, BaseType_t xTargetCoreID);
|
||||
|
||||
void vPortCleanUpCoprocArea( void *pxTCB )
|
||||
{
|
||||
UBaseType_t uxCoprocArea;
|
||||
BaseType_t xTargetCoreID;
|
||||
|
||||
/* Get pointer to the task's coprocessor save area from TCB->pxEndOfStack. See uxInitialiseStackCPSA() */
|
||||
uxCoprocArea = ( UBaseType_t ) ( ( ( StaticTask_t * ) pxTCB )->pxDummy8 ); /* Get TCB_t.pxEndOfStack */
|
||||
uxCoprocArea = STACKPTR_ALIGN_DOWN(16, uxCoprocArea - XT_CP_SIZE);
|
||||
|
||||
/* Extract core ID from the affinity mask */
|
||||
xTargetCoreID = ( ( StaticTask_t * ) pxTCB )->uxDummy25 ;
|
||||
xTargetCoreID = ( BaseType_t ) __builtin_ffs( ( int ) xTargetCoreID );
|
||||
assert( xTargetCoreID >= 1 ); // __builtin_ffs always returns first set index + 1
|
||||
xTargetCoreID -= 1;
|
||||
|
||||
/* If task has live floating point registers somewhere, release them */
|
||||
_xt_coproc_release( (void *)uxCoprocArea, xTargetCoreID );
|
||||
}
|
||||
#endif // ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
|
||||
// ------- Thread Local Storage Pointers Deletion Callbacks -------
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
void vPortTLSPointersDelCb( void *pxTCB )
|
||||
{
|
||||
/* Typecast pxTCB to StaticTask_t type to access TCB struct members.
|
||||
* pvDummy15 corresponds to pvThreadLocalStoragePointers member of the TCB.
|
||||
*/
|
||||
StaticTask_t *tcb = ( StaticTask_t * )pxTCB;
|
||||
|
||||
/* The TLSP deletion callbacks are stored at an offset of (configNUM_THREAD_LOCAL_STORAGE_POINTERS/2) */
|
||||
TlsDeleteCallbackFunction_t *pvThreadLocalStoragePointersDelCallback = ( TlsDeleteCallbackFunction_t * )( &( tcb->pvDummy15[ ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ] ) );
|
||||
|
||||
/* We need to iterate over half the depth of the pvThreadLocalStoragePointers area
|
||||
* to access all TLS pointers and their respective TLS deletion callbacks.
|
||||
*/
|
||||
for ( int x = 0; x < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ); x++ ) {
|
||||
if ( pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) { //If del cb is set
|
||||
/* In case the TLSP deletion callback has been overwritten by a TLS pointer, gracefully abort. */
|
||||
if ( !esp_ptr_executable( pvThreadLocalStoragePointersDelCallback[ x ] ) ) {
|
||||
// We call EARLY log here as currently portCLEAN_UP_TCB() is called in a critical section
|
||||
ESP_EARLY_LOGE("FreeRTOS", "Fatal error: TLSP deletion callback at index %d overwritten with non-excutable pointer %p", x, pvThreadLocalStoragePointersDelCallback[ x ]);
|
||||
abort();
|
||||
}
|
||||
|
||||
pvThreadLocalStoragePointersDelCallback[ x ]( x, tcb->pvDummy15[ x ] ); //Call del cb
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
|
||||
|
||||
// ------------------- Hook Functions ----------------------
|
||||
|
||||
@ -655,31 +684,3 @@ void vApplicationMinimalIdleHook( void )
|
||||
esp_vApplicationIdleHook(); //Run IDF style hooks
|
||||
}
|
||||
#endif // CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK
|
||||
|
||||
/*
|
||||
* Hook function called during prvDeleteTCB() to cleanup any
|
||||
* user defined static memory areas in the TCB.
|
||||
*/
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
void __real_vPortCleanUpTCB( void *pxTCB );
|
||||
|
||||
void __wrap_vPortCleanUpTCB( void *pxTCB )
|
||||
#else
|
||||
void vPortCleanUpTCB ( void *pxTCB )
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/* Call user defined vPortCleanUpTCB */
|
||||
__real_vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
|
||||
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
|
||||
/* Call TLS pointers deletion callbacks */
|
||||
vPortTLSPointersDelCb( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
|
||||
|
||||
#if ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
/* Cleanup coproc save area */
|
||||
vPortCleanUpCoprocArea( pxTCB );
|
||||
#endif // ( XCHAL_CP_NUM > 0 && configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 )
|
||||
}
|
||||
|
@ -427,7 +427,19 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
|
||||
return (BaseType_t) esp_cpu_get_core_id();
|
||||
}
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
/**
|
||||
* @brief TCB cleanup hook
|
||||
*
|
||||
* The portCLEAN_UP_TCB() macro is called in prvDeleteTCB() right before a
|
||||
* deleted task's memory is freed. We map that macro to this internal function
|
||||
* so that IDF FreeRTOS ports can inject some task pre-deletion operations.
|
||||
*
|
||||
* @note We can't use vPortCleanUpTCB() due to API compatibility issues. See
|
||||
* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP. Todo: IDF-8097
|
||||
*/
|
||||
void vPortTCBPreDeleteHook( void *pxTCB );
|
||||
|
||||
/* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
|
||||
* - Contains all the mappings of the macros required by FreeRTOS
|
||||
@ -561,11 +573,7 @@ FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void)
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
/* If enabled, users must provide an implementation of vPortCleanUpTCB() */
|
||||
extern void vPortCleanUpTCB ( void *pxTCB );
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB )
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortTCBPreDeleteHook( pxTCB )
|
||||
|
||||
// -------------- Optimized Task Selection -----------------
|
||||
|
||||
|
@ -589,7 +589,26 @@ void vPortSetStackWatchpoint(void *pxStackStart)
|
||||
esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, STACK_WATCH_AREA_SIZE, ESP_CPU_WATCHPOINT_STORE);
|
||||
}
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
void vPortTCBPreDeleteHook( void *pxTCB )
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK )
|
||||
/* Call the user defined task pre-deletion hook */
|
||||
extern void vTaskPreDeletionHook( void * pxTCB );
|
||||
vTaskPreDeletionHook( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK */
|
||||
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/*
|
||||
* If the user is using the legacy task pre-deletion hook, call it.
|
||||
* Todo: Will be removed in IDF-8097
|
||||
*/
|
||||
#warning "CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is deprecated. Use CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK instead."
|
||||
extern void vPortCleanUpTCB( void * pxTCB );
|
||||
vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- Misc Implementations -------------------------------------------------
|
||||
*
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
/*
|
||||
* FreeRTOS Kernel V10.4.3
|
||||
@ -406,6 +406,19 @@ void vPortSetStackWatchpoint( void *pxStackStart );
|
||||
*/
|
||||
FORCE_INLINE_ATTR BaseType_t xPortGetCoreID(void);
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
/**
|
||||
* @brief TCB cleanup hook
|
||||
*
|
||||
* The portCLEAN_UP_TCB() macro is called in prvDeleteTCB() right before a
|
||||
* deleted task's memory is freed. We map that macro to this internal function
|
||||
* so that IDF FreeRTOS ports can inject some task pre-deletion operations.
|
||||
*
|
||||
* @note We can't use vPortCleanUpTCB() due to API compatibility issues. See
|
||||
* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP. Todo: IDF-8097
|
||||
*/
|
||||
void vPortTCBPreDeleteHook( void *pxTCB );
|
||||
|
||||
|
||||
/* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
|
||||
@ -525,11 +538,7 @@ extern void _frxt_setup_switch( void ); //Defined in portasm.S
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
/* If enabled, users must provide an implementation of vPortCleanUpTCB() */
|
||||
extern void vPortCleanUpTCB ( void *pxTCB );
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortCleanUpTCB( pxTCB )
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
#define portCLEAN_UP_TCB( pxTCB ) vPortTCBPreDeleteHook( pxTCB )
|
||||
|
||||
// -------------- Optimized Task Selection -----------------
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
/*
|
||||
* FreeRTOS Kernel V10.4.3
|
||||
@ -605,6 +605,27 @@ void vPortSetStackWatchpoint( void *pxStackStart )
|
||||
esp_cpu_set_watchpoint(STACK_WATCH_POINT_NUMBER, (char *)addr, 32, ESP_CPU_WATCHPOINT_STORE);
|
||||
}
|
||||
|
||||
// --------------------- TCB Cleanup -----------------------
|
||||
|
||||
void vPortTCBPreDeleteHook( void *pxTCB )
|
||||
{
|
||||
#if ( CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK )
|
||||
/* Call the user defined task pre-deletion hook */
|
||||
extern void vTaskPreDeletionHook( void * pxTCB );
|
||||
vTaskPreDeletionHook( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK */
|
||||
|
||||
#if ( CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP )
|
||||
/*
|
||||
* If the user is using the legacy task pre-deletion hook, call it.
|
||||
* Todo: Will be removed in IDF-8097
|
||||
*/
|
||||
#warning "CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is deprecated. Use CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK instead."
|
||||
extern void vPortCleanUpTCB( void * pxTCB );
|
||||
vPortCleanUpTCB( pxTCB );
|
||||
#endif /* CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP */
|
||||
}
|
||||
|
||||
// -------------------- Co-Processor -----------------------
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
@ -324,10 +324,28 @@ menu "FreeRTOS"
|
||||
callbacks. If the user does not wish to use TLSP deletion callbacks then this option could be turned
|
||||
off to save space in the TCB memory.
|
||||
|
||||
config FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
bool "Enable static task clean up hook"
|
||||
config FREERTOS_TASK_PRE_DELETION_HOOK
|
||||
# This option is a replacement for FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP (which is now deprecated). If the
|
||||
# deprecated option is defined, we hide this option to avoid multiple pre-deletion hooks from running.
|
||||
bool "Enable task pre-deletion hook"
|
||||
depends on !FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
default n
|
||||
help
|
||||
Enable this option to make FreeRTOS call a user provided hook function right before it deletes a task
|
||||
(i.e., frees/releases a dynamically/statically allocated task's memory). This is useful if users want
|
||||
to know when a task is actually deleted (in case the task's deletion is delegated to the IDLE task).
|
||||
|
||||
If this config option is enabled, users must define a ``void vTaskPreDeletionHook( void * pxTCB )``
|
||||
hook function in their application.
|
||||
|
||||
config FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
# This option is deprecated (replaced by FREERTOS_TASK_PRE_DELETION_HOOK) but still exists to maintain
|
||||
# compatibility. Todo: Remove by v6.0 (see IDF-8097).
|
||||
bool "Enable static task clean up hook (DEPRECATED)"
|
||||
default n
|
||||
help
|
||||
THIS OPTION IS DEPRECATED. Use FREERTOS_TASK_PRE_DELETION_HOOK instead.
|
||||
|
||||
Enable this option to make FreeRTOS call the static task clean up hook when a task is deleted.
|
||||
|
||||
Note: Users will need to provide a ``void vPortCleanUpTCB ( void *pxTCB )`` callback
|
||||
|
@ -219,7 +219,7 @@ entries:
|
||||
port:vPortCleanUpCoprocArea (default)
|
||||
if FREERTOS_TLSP_DELETION_CALLBACKS = y:
|
||||
port:vPortTLSPointersDelCb (default)
|
||||
port:vPortCleanUpTCB (default)
|
||||
port:vPortTCBPreDeleteHook (default)
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
# portable/riscv/port.c
|
||||
# - Most functions are called from an ISR context, except for scheduler/task init/deinit functions
|
||||
@ -234,4 +234,4 @@ entries:
|
||||
port:pxPortInitialiseStack (default)
|
||||
if FREERTOS_TLSP_DELETION_CALLBACKS = y:
|
||||
port:vPortTLSPointersDelCb (default)
|
||||
port:vPortCleanUpTCB (default)
|
||||
port:vPortTCBPreDeleteHook (default)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -65,7 +65,7 @@ TEST_CASE("FreeRTOS tick hook", "[freertos]")
|
||||
#endif // configUSE_TICK_HOOK
|
||||
#endif // CONFIG_FREERTOS_SMP
|
||||
|
||||
#if CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
#if CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK
|
||||
|
||||
static volatile void *deleted_tcb;
|
||||
|
||||
@ -74,7 +74,7 @@ static void taskDeletesItself(void *ignored)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void vPortCleanUpTCB(void *pxTCB)
|
||||
void vTaskPreDeletionHook(void *pxTCB)
|
||||
{
|
||||
deleted_tcb = pxTCB;
|
||||
}
|
||||
@ -91,4 +91,4 @@ TEST_CASE("static task cleanup hook is called based on config", "[freertos]")
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP
|
||||
#endif // CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -105,15 +105,6 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]")
|
||||
//The variables pointed to by Thread Local Storage Pointer
|
||||
static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0};
|
||||
|
||||
/* If static task cleanup is defined, can't set index 0 even if the calling task is not a pthread,
|
||||
as the cleanup is called for every task.
|
||||
*/
|
||||
#if defined(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP)
|
||||
static const int skip_index = 0; /*PTHREAD_TLS_INDEX*/
|
||||
#else
|
||||
static const int skip_index = -1;
|
||||
#endif
|
||||
|
||||
static void del_cb(int index, void *ptr)
|
||||
{
|
||||
*((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value
|
||||
@ -123,19 +114,11 @@ static void task_cb(void *arg)
|
||||
{
|
||||
int core = xPortGetCoreID();
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element
|
||||
}
|
||||
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i);
|
||||
TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value
|
||||
}
|
||||
@ -153,9 +136,6 @@ TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]"
|
||||
|
||||
for(int core = 0; core < portNUM_PROCESSORS; core++){
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL=y
|
||||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
CONFIG_FREERTOS_INTERRUPT_BACKTRACE=n
|
||||
CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
|
||||
CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
|
||||
CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK=y
|
||||
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=10
|
||||
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
||||
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
|
||||
|
@ -103,15 +103,6 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]")
|
||||
//The variables pointed to by Thread Local Storage Pointer
|
||||
static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0};
|
||||
|
||||
/* If static task cleanup is defined, can't set index 0 even if the calling task is not a pthread,
|
||||
as the cleanup is called for every task.
|
||||
*/
|
||||
#if defined(CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP)
|
||||
static const int skip_index = 0; /*PTHREAD_TLS_INDEX*/
|
||||
#else
|
||||
static const int skip_index = -1;
|
||||
#endif
|
||||
|
||||
static void del_cb(int index, void *ptr)
|
||||
{
|
||||
*((uint32_t *)ptr) = (TLSP_DEL_BASE << index); //Indicate deletion by setting task storage element to a unique value
|
||||
@ -121,19 +112,11 @@ static void task_cb(void *arg)
|
||||
{
|
||||
int core = xPortGetCoreID();
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
task_storage[core][i] = (TLSP_SET_BASE << i); //Give each element of task_storage a unique number
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, i, (void *)&task_storage[core][i], del_cb); //Set each TLSP to point to a task storage element
|
||||
}
|
||||
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t * tlsp = (uint32_t *)pvTaskGetThreadLocalStoragePointer(NULL, i);
|
||||
TEST_ASSERT_EQUAL(*tlsp, (TLSP_SET_BASE << i)); //Check if TLSP points to the correct task storage element by checking unique value
|
||||
}
|
||||
@ -151,9 +134,6 @@ TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]"
|
||||
|
||||
for(int core = 0; core < portNUM_PROCESSORS; core++){
|
||||
for(int i = 0; i < NO_OF_TLSP; i++){
|
||||
if (i == skip_index) {
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user