diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h b/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h index 4df12a4031..e6b6916ab9 100644 --- a/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h +++ b/components/freertos/FreeRTOS-Kernel/include/freertos/FreeRTOS.h @@ -1247,9 +1247,6 @@ typedef struct xSTATIC_TCB #endif #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - void * pvDummyLocalStorageCallBack[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #endif #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) uint32_t ulDummy16; diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index fda5f44e0d..3682aa7aa8 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -591,6 +591,34 @@ void vPortSetStackWatchpoint(void *pxStackStart) // --------------------- 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 ) @@ -608,6 +636,11 @@ void vPortTCBPreDeleteHook( void *pxTCB ) 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 */ } /* ---------------------------------------------- Misc Implementations ------------------------------------------------- diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 5ab57f22d0..92b7174141 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -607,6 +607,35 @@ void vPortSetStackWatchpoint( void *pxStackStart ) // --------------------- 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 ) static void vPortCleanUpCoprocArea(void *pvTCB) { @@ -644,6 +673,11 @@ void vPortTCBPreDeleteHook( 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 ) /* Cleanup coproc save area */ vPortCleanUpCoprocArea( pxTCB ); diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 88fd618de6..9487213e2a 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -379,9 +379,6 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - TlsDeleteCallbackFunction_t pvThreadLocalStoragePointersDelCallback[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #endif #endif #if ( configGENERATE_RUN_TIME_STATS == 1 ) @@ -572,13 +569,6 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; #endif -/* Function to call the Thread Local Storage Pointer Deletion Callbacks. Will be - * called during task deletion before prvDeleteTCB is called. - */ -#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - static void prvDeleteTLS( TCB_t * pxTCB ); -#endif - /* * Used only by the idle task. This checks to see if anything has been placed * in the list of tasks waiting to be deleted. If so the task is cleaned up @@ -1167,9 +1157,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) { pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; - #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - pxNewTCB->pvThreadLocalStoragePointersDelCallback[ x ] = NULL; - #endif } } #endif @@ -1514,10 +1501,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) if( xFreeNow == pdTRUE ) { - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif - prvDeleteTCB( pxTCB ); } @@ -4468,7 +4451,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) { TCB_t * pxTCB; - if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + /* If TLSP deletion callbacks are enabled, then + * configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so + * that the latter half of the pvThreadLocalStoragePointers stores + * the deletion callbacks. */ + if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) { #if ( configNUM_CORES > 1 ) @@ -4479,8 +4466,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) #endif /* ( configNUM_CORES > 1 ) */ pxTCB = prvGetTCBFromHandle( xTaskToSet ); + /* Store the TLSP by indexing the first half of the array */ pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; - pxTCB->pvThreadLocalStoragePointersDelCallback[ xIndex ] = xDelCallback; + /* Store the TLSP deletion callback by indexing the second half + * of the array. */ + pxTCB->pvThreadLocalStoragePointers[ ( xIndex + ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) ] = ( void * ) xDelCallback; #if ( configNUM_CORES > 1 ) /* Release the previously taken kernel lock. */ @@ -4537,7 +4527,15 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) void * pvReturn = NULL; TCB_t * pxTCB; - if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) + /* If TLSP deletion callbacks are enabled, then + * configNUM_THREAD_LOCAL_STORAGE_POINTERS is doubled in size so + * that the latter half of the pvThreadLocalStoragePointers stores + * the deletion callbacks. */ + if( xIndex < ( configNUM_THREAD_LOCAL_STORAGE_POINTERS / 2 ) ) + #else /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */ + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + #endif /* configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 */ { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; @@ -4648,9 +4646,6 @@ static void prvCheckTasksWaitingTermination( void ) if ( pxTCB != NULL ) { - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif prvDeleteTCB( pxTCB ); } else @@ -4668,9 +4663,6 @@ static void prvCheckTasksWaitingTermination( void ) } taskEXIT_CRITICAL( &xKernelLock ); - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - prvDeleteTLS( pxTCB ); - #endif prvDeleteTCB( pxTCB ); #endif /* configNUM_CORES > 1 */ } @@ -4990,25 +4982,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) #endif /* INCLUDE_vTaskDelete */ /*-----------------------------------------------------------*/ -#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) - - static void prvDeleteTLS( TCB_t * pxTCB ) - { - configASSERT( pxTCB ); - - for( int x = 0; x < configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) - { - if( pxTCB->pvThreadLocalStoragePointersDelCallback[ x ] != NULL ) /*If del cb is set */ - { - pxTCB->pvThreadLocalStoragePointersDelCallback[ x ]( x, pxTCB->pvThreadLocalStoragePointers[ x ] ); /*Call del cb */ - } - } - } - -#endif /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) && ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS == 1 ) */ -/*-----------------------------------------------------------*/ - - static void prvResetNextTaskUnblockTime( void ) { TCB_t * pxTCB; diff --git a/components/freertos/config/include/freertos/FreeRTOSConfig.h b/components/freertos/config/include/freertos/FreeRTOSConfig.h index 26cec5b97b..6a7ccf6d19 100644 --- a/components/freertos/config/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/config/include/freertos/FreeRTOSConfig.h @@ -109,15 +109,16 @@ #define configMAX_TASK_NAME_LEN CONFIG_FREERTOS_MAX_TASK_NAME_LEN -/* The distinciton between Amazon SMP FreeRTOS and IDF FreeRTOS is necessary because in IDF FreeRTOS, - * TLSP deletion callbacks can be added directly to the TCB, which is not allowed in Amazon SMP FreeRTOS. - * In the latter, the TLSP number is simply doubled to accomodate space for a deletion callback of each TLSP. - */ -#if CONFIG_FREERTOS_SMP +/* If deletion callbacks are enabled, the number of TLSP's are doubled (i.e., + * the length of the TCB's pvThreadLocalStoragePointersThis array). This allows + * the latter half of the array to store the deletion callback pointers (whereas + * the first half stores the TLSPs themselves). */ +#if CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS #define configNUM_THREAD_LOCAL_STORAGE_POINTERS ( CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS * 2 ) -#else /* CONFIG_FREERTOS_SMP */ +#else /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ #define configNUM_THREAD_LOCAL_STORAGE_POINTERS CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS -#endif /* CONFIG_FREERTOS_SMP */ +#endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */ + #define configSTACK_DEPTH_TYPE uint32_t #if CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY #define configENABLE_BACKWARD_COMPATIBILITY 1 diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index e7e75a3845..f23fac8bfe 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -153,7 +153,6 @@ entries: tasks:prvIdleTask (default) if FREERTOS_TLSP_DELETION_CALLBACKS = y: tasks:vTaskSetThreadLocalStoragePointerAndDelCallback (default) - tasks:prvDeleteTLS (default) if FREERTOS_THREAD_LOCAL_STORAGE_POINTERS != 0: tasks:vTaskSetThreadLocalStoragePointer (default) tasks:pvTaskGetThreadLocalStoragePointer (default) @@ -234,6 +233,8 @@ entries: port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) port:xPortGetTickRateHz (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S3 = y : port:vPortCleanUpCoprocArea (default) port:vPortTCBPreDeleteHook (default) @@ -246,4 +247,6 @@ entries: port:vPortEndScheduler (default) port:pxPortInitialiseStack (default) port:xPortGetTickRateHz (default) + if FREERTOS_TLSP_DELETION_CALLBACKS = y: + port:vPortTLSPointersDelCb (default) port:vPortTCBPreDeleteHook (default) diff --git a/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c b/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c index 4c3082fbd9..66eec9223c 100644 --- a/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c +++ b/components/freertos/test_apps/freertos/port/test_tlsp_del_cb.c @@ -6,8 +6,6 @@ #include "sdkconfig.h" -#if CONFIG_FREERTOS_SMP - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" @@ -79,66 +77,3 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]") } } } - -#else // CONFIG_FREERTOS_SMP - -// Todo: Remove IDF FreeRTOS Test Case - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "unity.h" -#include "test_utils.h" - -/* --------Test backported thread local storage pointer and deletion cb feature---------- - * vTaskSetThreadLocalStoragePointerAndDelCallback() - * pvTaskGetThreadLocalStoragePointer(), - * - * This test creates a task and set's the task's TLSPs. The task is then deleted - * which should trigger the deletion cb. - */ - -#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS -#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index -#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index - -//The variables pointed to by Thread Local Storage Pointer -static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0}; - -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 -} - -static void task_cb(void *arg) -{ - int core = xPortGetCoreID(); - for(int i = 0; i < NO_OF_TLSP; i++){ - 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++){ - 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 - } - - vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback -} - -TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]") -{ - //Create Task - for(int core = 0; core < portNUM_PROCESSORS; core++){ - xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, UNITY_FREERTOS_PRIORITY+1, NULL, core); - } - vTaskDelay(10); //Delay long enough for tasks to run to completion - - for(int core = 0; core < portNUM_PROCESSORS; core++){ - for(int i = 0; i < NO_OF_TLSP; i++){ - TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value - } - } -} - -#endif // CONFIG_FREERTOS_SMP diff --git a/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c b/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c index 289b86df44..7de13ae355 100644 --- a/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c +++ b/tools/test_apps/linux_compatible/linux_freertos/components/kernel_tests/port/test_tlsp_del_cb.c @@ -6,8 +6,6 @@ #include "sdkconfig.h" -#if CONFIG_FREERTOS_SMP - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" @@ -78,65 +76,3 @@ TEST_CASE("Test TLSP deletion callbacks", "[freertos]") } } } - -#else // CONFIG_FREERTOS_SMP - -// Todo: Remove IDF FreeRTOS Test Case - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "unity.h" - -/* --------Test backported thread local storage pointer and deletion cb feature---------- - * vTaskSetThreadLocalStoragePointerAndDelCallback() - * pvTaskGetThreadLocalStoragePointer(), - * - * This test creates a task and set's the task's TLSPs. The task is then deleted - * which should trigger the deletion cb. - */ - -#define NO_OF_TLSP configNUM_THREAD_LOCAL_STORAGE_POINTERS -#define TLSP_SET_BASE 0x0F //0b1111 to be bit shifted by index -#define TLSP_DEL_BASE 0x05 //0b0101 to be bit shifted by index - -//The variables pointed to by Thread Local Storage Pointer -static uint32_t task_storage[portNUM_PROCESSORS][NO_OF_TLSP] = {0}; - -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 -} - -static void task_cb(void *arg) -{ - int core = xPortGetCoreID(); - for(int i = 0; i < NO_OF_TLSP; i++){ - 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++){ - 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 - } - - vTaskDelete(NULL); //Delete Task to Trigger TSLP deletion callback -} - -TEST_CASE("Test FreeRTOS thread local storage pointers and del cb", "[freertos]") -{ - //Create Task - for(int core = 0; core < portNUM_PROCESSORS; core++){ - xTaskCreatePinnedToCore(task_cb, "task", 1024, NULL, CONFIG_UNITY_FREERTOS_PRIORITY+1, NULL, core); - } - vTaskDelay(10); //Delay long enough for tasks to run to completion - - for(int core = 0; core < portNUM_PROCESSORS; core++){ - for(int i = 0; i < NO_OF_TLSP; i++){ - TEST_ASSERT_EQUAL((TLSP_DEL_BASE << i), task_storage[core][i]); //Check del_cb ran by checking task storage for unique value - } - } -} - -#endif // CONFIG_FREERTOS_SMP