From 0db40f9e6cbb4cdf632728f491205be311a63c0b Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 29 Aug 2023 02:07:52 +0800 Subject: [PATCH] refactor(freertos/idf): Move IDF task utility functions to API addition headers This commit combines various task utility API additions in IDF FreeRTOS and with their Amazon SMP FreeRTOS addition counterparts. The folloiwng functions have been moved to freertos_tasks_c_additions.h and idf_additions.h as these API are considered public: - xTaskGetCurrentTaskHandleForCPU() - xTaskGetIdleTaskHandleForCPU() - xTaskGetAffinity() - pxTaskGetStackStart() Also fixed in missing #if macros when vTaskCoreAffinityGet() is called in Amazon SMP FreerTOS tests. --- .../FreeRTOS-Kernel/include/freertos/task.h | 41 ------ components/freertos/FreeRTOS-Kernel/tasks.c | 45 +------ .../config/include/freertos/FreeRTOSConfig.h | 2 - .../freertos_tasks_c_additions.h | 117 ++++++++++++------ .../include/freertos/idf_additions.h | 70 ++++++----- components/freertos/linker.lf | 4 - components/freertos/linker_common.lf | 2 + .../test_apps/freertos/port/test_fpu_in_isr.c | 4 + .../freertos/port/test_fpu_in_task.c | 4 + 9 files changed, 126 insertions(+), 163 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/task.h b/components/freertos/FreeRTOS-Kernel/include/freertos/task.h index 7e898b2d32..0cffaf5e5c 100644 --- a/components/freertos/FreeRTOS-Kernel/include/freertos/task.h +++ b/components/freertos/FreeRTOS-Kernel/include/freertos/task.h @@ -1950,21 +1950,6 @@ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTIO */ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; -/** - * Returns the start of the stack associated with xTask. - * - * INCLUDE_pxTaskGetStackStart must be set to 1 in FreeRTOSConfig.h for - * this function to be available. - * - * Returns the lowest stack memory address, regardless of whether the stack grows up or down. - * - * @param xTask Handle of the task associated with the stack returned. - * Set xTask to NULL to return the stack of the calling task. - * - * @return A pointer to the start of the stack. - */ -uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; - /* When using trace macros it is sometimes necessary to include task.h before * FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, * so the following two prototypes will cause a compilation error. This can be @@ -3439,32 +3424,6 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** @cond !DOC_EXCLUDE_HEADER_SECTION */ -/* - * Return the handle of the task running on a certain CPU. Because of - * the nature of SMP processing, there is no guarantee that this - * value will still be valid on return and should only be used for - * debugging purposes. - */ -TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid ); - -/** - * Get the handle of idle task for the given CPU. - * - * xTaskGetIdleTaskHandleForCPU() is only available if - * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. - * - * @param cpuid The CPU to get the handle for - * - * @return Idle task handle of a given cpu. It is not valid to call - * xTaskGetIdleTaskHandleForCPU() before the scheduler has been started. - */ -TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid ); - -/* - * Get the current core affinity of a task - */ -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; - /* * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index c55fa6a927..98de5987ff 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -3016,12 +3016,6 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char return xIdleTaskHandle[ xPortGetCoreID() ]; } - TaskHandle_t xTaskGetIdleTaskHandleForCPU( UBaseType_t cpuid ) - { - configASSERT( cpuid < configNUM_CORES ); - configASSERT( ( xIdleTaskHandle[ cpuid ] != NULL ) ); - return xIdleTaskHandle[ cpuid ]; - } #endif /* INCLUDE_xTaskGetIdleTaskHandle */ /*----------------------------------------------------------*/ @@ -4677,16 +4671,6 @@ static void prvCheckTasksWaitingTermination( void ) #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ -BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) -{ - TCB_t * pxTCB; - - pxTCB = prvGetTCBFromHandle( xTask ); - - return pxTCB->xCoreID; -} -/*-----------------------------------------------------------*/ - #if ( configUSE_TRACE_FACILITY == 1 ) static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray, @@ -4809,20 +4793,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) #endif /* INCLUDE_uxTaskGetStackHighWaterMark */ /*-----------------------------------------------------------*/ -#if ( INCLUDE_pxTaskGetStackStart == 1 ) - - uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) - { - TCB_t * pxTCB; - uint8_t * uxReturn; - - pxTCB = prvGetTCBFromHandle( xTask ); - uxReturn = ( uint8_t * ) pxTCB->pxStack; - - return uxReturn; - } - -#endif /* INCLUDE_pxTaskGetStackStart */ #if ( INCLUDE_vTaskDelete == 1 ) @@ -4910,7 +4880,7 @@ static void prvResetNextTaskUnblockTime( void ) } /*-----------------------------------------------------------*/ -#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) || ( configNUM_CORES > 1 ) ) +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) TaskHandle_t xTaskGetCurrentTaskHandle( void ) { @@ -4924,19 +4894,6 @@ static void prvResetNextTaskUnblockTime( void ) return xReturn; } - TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t cpuid ) - { - TaskHandle_t xReturn = NULL; - - /*Xtensa-specific: the pxCurrentPCB pointer is atomic so we shouldn't need a lock. */ - if( cpuid < configNUM_CORES ) - { - xReturn = pxCurrentTCB[ cpuid ]; - } - - return xReturn; - } - #endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ /*-----------------------------------------------------------*/ diff --git a/components/freertos/config/include/freertos/FreeRTOSConfig.h b/components/freertos/config/include/freertos/FreeRTOSConfig.h index 6a7ccf6d19..35faea2145 100644 --- a/components/freertos/config/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/config/include/freertos/FreeRTOSConfig.h @@ -198,8 +198,6 @@ #define INCLUDE_xTaskResumeFromISR 1 #define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xTaskGetSchedulerState 1 -/* Unlisted */ -#define INCLUDE_pxTaskGetStackStart 1 /* -------------------- Trace Macros ----------------------- */ diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index 7f45a52219..b37933d79d 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -244,64 +244,101 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt /* ------------------------------------------------- Task Utilities ------------------------------------------------- */ -#if CONFIG_FREERTOS_SMP - - TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ) - { - TaskHandle_t xTaskHandleTemp; - - assert( xCoreID >= 0 && xCoreID < configNUM_CORES ); - taskENTER_CRITICAL(); - xTaskHandleTemp = ( TaskHandle_t ) pxCurrentTCBs[ xCoreID ]; - taskEXIT_CRITICAL(); - return xTaskHandleTemp; - } - -#endif /* CONFIG_FREERTOS_SMP */ -/*----------------------------------------------------------*/ - -#if CONFIG_FREERTOS_SMP +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ) { - assert( xCoreID >= 0 && xCoreID < configNUM_CORES ); + configASSERT( xCoreID >= 0 && xCoreID < configNUM_CORES ); + configASSERT( ( xIdleTaskHandle[ xCoreID ] != NULL ) ); return ( TaskHandle_t ) xIdleTaskHandle[ xCoreID ]; } -#endif /* CONFIG_FREERTOS_SMP */ +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ /*----------------------------------------------------------*/ -#if CONFIG_FREERTOS_SMP +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) - BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) + TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ) { - taskENTER_CRITICAL(); - UBaseType_t uxCoreAffinityMask; - #if ( configUSE_CORE_AFFINITY == 1 && configNUM_CORES > 1 ) - TCB_t * pxTCB = prvGetTCBFromHandle( xTask ); - uxCoreAffinityMask = pxTCB->uxCoreAffinityMask; - #else - uxCoreAffinityMask = tskNO_AFFINITY; - #endif - taskEXIT_CRITICAL(); - BaseType_t ret; + TaskHandle_t xReturn; - /* If the task is not pinned to a particular core, treat it as tskNO_AFFINITY */ - if( uxCoreAffinityMask & ( uxCoreAffinityMask - 1 ) ) /* If more than one bit set */ + #if CONFIG_FREERTOS_SMP { - ret = tskNO_AFFINITY; + xReturn = xTaskGetCurrentTaskHandleCPU( xCoreID ); } - else + #else /* CONFIG_FREERTOS_SMP */ { - int index_plus_one = __builtin_ffs( uxCoreAffinityMask ); - assert( index_plus_one >= 1 ); - ret = index_plus_one - 1; + if( xCoreID < configNUM_CORES ) + { + xReturn = pxCurrentTCB[ xCoreID ]; + } + else + { + xReturn = NULL; + } } + #endif /* CONFIG_FREERTOS_SMP */ - return ret; + return xReturn; } -#endif /* CONFIG_FREERTOS_SMP */ +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) +{ + BaseType_t xReturn; + + #if ( configNUM_CORES > 1 ) + { + #if CONFIG_FREERTOS_SMP + UBaseType_t uxCoreAffinityMask; + + /* Get the core affinity mask and covert it to an ID */ + uxCoreAffinityMask = vTaskCoreAffinityGet( xTask ); + + /* If the task is not pinned to a particular core, treat it as tskNO_AFFINITY */ + if( uxCoreAffinityMask & ( uxCoreAffinityMask - 1 ) ) /* If more than one bit set */ + { + xReturn = tskNO_AFFINITY; + } + else + { + int iIndexPlusOne = __builtin_ffs( uxCoreAffinityMask ); + assert( iIndexPlusOne >= 1 ); + xReturn = iIndexPlusOne - 1; + } + #else /* CONFIG_FREERTOS_SMP */ + TCB_t * pxTCB; + + pxTCB = prvGetTCBFromHandle( xTask ); + /* Simply read the xCoreID member of the TCB */ + taskENTER_CRITICAL( &xKernelLock ); + xReturn = pxTCB->xCoreID; + taskEXIT_CRITICAL_ISR( &xKernelLock ); + #endif /* CONFIG_FREERTOS_SMP */ + } + #else /* configNUM_CORES > 1 */ + { + /* Single-core. Just return a core ID of 0 */ + xReturn = 0; + } + #endif /* configNUM_CORES > 1 */ + + return xReturn; +} +/*----------------------------------------------------------*/ + +uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ) +{ + TCB_t * pxTCB; + uint8_t * uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = ( uint8_t * ) pxTCB->pxStack; + + return uxReturn; +} /*----------------------------------------------------------*/ #if ( INCLUDE_vTaskPrioritySet == 1 ) diff --git a/components/freertos/esp_additions/include/freertos/idf_additions.h b/components/freertos/esp_additions/include/freertos/idf_additions.h index 41ca5ee14a..3d9574973b 100644 --- a/components/freertos/esp_additions/include/freertos/idf_additions.h +++ b/components/freertos/esp_additions/include/freertos/idf_additions.h @@ -103,45 +103,35 @@ #endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ -/* ------------------------------------------------- Task Utilities ---------------------------------------------------- - * Todo: Move IDF FreeRTOS SMP related additions to this header as well (see IDF-7201) - * ------------------------------------------------------------------------------------------------------------------ */ - -#if CONFIG_FREERTOS_SMP +/* ------------------------------------------------- Task Utilities ------------------------------------------------- */ /** - * @brief Get the handle of the task running on a certain core + * @brief Get the handle of idle task for the given core. + * + * [refactor-todo] See if this needs to be deprecated (IDF-8145) + * + * @note If CONFIG_FREERTOS_SMP is enabled, please call xTaskGetIdleTaskHandle() + * instead. + * @param xCoreID The core to query + * @return Handle of the idle task for the queried core + */ +TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ); + +/** + * @brief Get the handle of the task currently running on a certain core * * Because of the nature of SMP processing, there is no guarantee that this * value will still be valid on return and should only be used for debugging * purposes. * - * [refactor-todo] Mark this function as deprecated, call - * xTaskGetCurrentTaskHandleCPU() instead + * [refactor-todo] See if this needs to be deprecated (IDF-8145) * + * @note If CONFIG_FREERTOS_SMP is enabled, please call xTaskGetCurrentTaskHandleCPU() + * instead. * @param xCoreID The core to query * @return Handle of the current task running on the queried core */ - TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ); - -#endif /* CONFIG_FREERTOS_SMP */ - -#if CONFIG_FREERTOS_SMP - -/** - * @brief Get the handle of idle task for the given CPU. - * - * [refactor-todo] Mark this function as deprecated, call - * xTaskGetIdleTaskHandle() instead - * - * @param xCoreID The core to query - * @return Handle of the idle task for the queried core - */ - TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID ); - -#endif /* CONFIG_FREERTOS_SMP */ - -#if CONFIG_FREERTOS_SMP +TaskHandle_t xTaskGetCurrentTaskHandleForCPU( BaseType_t xCoreID ); /** * @brief Get the current core affinity of a particular task @@ -150,15 +140,31 @@ * pinned to a particular core, the core ID is returned. If the task is not * pinned to a particular core, tskNO_AFFINITY is returned. * - * [refactor-todo] Mark this function as deprecated, call vTaskCoreAffinityGet() - * instead + * If CONFIG_FREERTOS_UNICORE is enabled, this function simply returns 0. * + * [refactor-todo] See if this needs to be deprecated (IDF-8145)(IDF-8164) + * + * @note If CONFIG_FREERTOS_SMP is enabled, please call vTaskCoreAffinityGet() + * instead. * @param xTask The task to query * @return The tasks coreID or tskNO_AFFINITY */ - BaseType_t xTaskGetAffinity( TaskHandle_t xTask ); +BaseType_t xTaskGetAffinity( TaskHandle_t xTask ); -#endif /* CONFIG_FREERTOS_SMP */ +/** + * Returns the start of the stack associated with xTask. + * + * Returns the lowest stack memory address, regardless of whether the stack + * grows up or down. + * + * [refactor-todo] Change return type to StackType_t (IDF-8158) + * + * @param xTask Handle of the task associated with the stack returned. + * Set xTask to NULL to return the stack of the calling task. + * + * @return A pointer to the start of the stack. + */ +uint8_t * pxTaskGetStackStart( TaskHandle_t xTask ); /* --------------------------------------------- TLSP Deletion Callbacks ----------------------------------------------- * TLSP Deletion Callback API Additions diff --git a/components/freertos/linker.lf b/components/freertos/linker.lf index 23ff389917..5b2c149d18 100644 --- a/components/freertos/linker.lf +++ b/components/freertos/linker.lf @@ -133,7 +133,6 @@ entries: tasks:prvSearchForNameWithinSingleList (default) tasks:xTaskGetHandle (default) tasks:xTaskGetIdleTaskHandle (default) - tasks:xTaskGetIdleTaskHandleForCPU (default) tasks:xTaskAbortDelay (default) # IDF-6410 Application tags not supported yet #tasks:vTaskSetApplicationTaskTag (default) @@ -155,14 +154,11 @@ entries: tasks:pvTaskGetThreadLocalStoragePointer (default) tasks:prvInitialiseTaskLists (default) tasks:prvCheckTasksWaitingTermination (default) - tasks:xTaskGetAffinity (default) tasks:prvTaskCheckFreeStackSpace (default) tasks:uxTaskGetStackHighWaterMark2 (default) tasks:uxTaskGetStackHighWaterMark (default) - tasks:pxTaskGetStackStart (default) tasks:prvDeleteTCB (default) tasks:xTaskGetCurrentTaskHandle (default) - tasks:xTaskGetCurrentTaskHandleForCPU (default) tasks:xTaskPriorityInherit (default) tasks:xTaskPriorityDisinherit (default) tasks:vTaskPriorityDisinheritAfterTimeout (default) diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf index ee61f1d03c..4a19d9764d 100644 --- a/components/freertos/linker_common.lf +++ b/components/freertos/linker_common.lf @@ -28,7 +28,9 @@ entries: # Task Utilities tasks:xTaskGetCurrentTaskHandleForCPU (default) tasks:xTaskGetIdleTaskHandleForCPU (default) + tasks:xTaskGetCurrentTaskHandleForCPU (default) tasks:xTaskGetAffinity (default) + tasks:pxTaskGetStackStart (default) tasks:prvTaskPriorityRaise (default) tasks:prvTaskPriorityRestore (default) # TLSP Deletion Callbacks diff --git a/components/freertos/test_apps/freertos/port/test_fpu_in_isr.c b/components/freertos/test_apps/freertos/port/test_fpu_in_isr.c index 2917f3c0b7..3ca6e90046 100644 --- a/components/freertos/test_apps/freertos/port/test_fpu_in_isr.c +++ b/components/freertos/test_apps/freertos/port/test_fpu_in_isr.c @@ -115,11 +115,13 @@ static void unpinned_task(void *arg) vTaskSuspendAll(); #endif // Check that the task is unpinned +#if !CONFIG_FREERTOS_UNICORE #if CONFIG_FREERTOS_SMP TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL)); #else TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL)); #endif +#endif // !CONFIG_FREERTOS_UNICORE // Allocate an ISR to use the FPU intr_handle_t isr_handle; @@ -130,11 +132,13 @@ static void unpinned_task(void *arg) esp_intr_free(isr_handle); // Task should remain unpinned after the ISR uses the FPU +#if !CONFIG_FREERTOS_UNICORE #if CONFIG_FREERTOS_SMP TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL)); #else TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL)); #endif +#endif // !CONFIG_FREERTOS_UNICORE // Reenable scheduling/preemption #if CONFIG_FREERTOS_SMP vTaskPreemptionEnable(NULL); diff --git a/components/freertos/test_apps/freertos/port/test_fpu_in_task.c b/components/freertos/test_apps/freertos/port/test_fpu_in_task.c index a829ed9adf..6bde01e388 100644 --- a/components/freertos/test_apps/freertos/port/test_fpu_in_task.c +++ b/components/freertos/test_apps/freertos/port/test_fpu_in_task.c @@ -137,11 +137,13 @@ static void unpinned_task(void *arg) #endif BaseType_t cur_core_num = xPortGetCoreID(); // Check that the task is unpinned +#if !CONFIG_FREERTOS_UNICORE #if CONFIG_FREERTOS_SMP TEST_ASSERT_EQUAL(tskNO_AFFINITY, vTaskCoreAffinityGet(NULL)); #else TEST_ASSERT_EQUAL(tskNO_AFFINITY, xTaskGetAffinity(NULL)); #endif +#endif // !CONFIG_FREERTOS_UNICORE /* Use the FPU @@ -156,11 +158,13 @@ static void unpinned_task(void *arg) // We allow a 0.1% delta on the final result in case of any loss of precision from floating point calculations TEST_ASSERT_FLOAT_WITHIN(0.00256f, 2.56f, test_float); +#if !CONFIG_FREERTOS_UNICORE #if CONFIG_FREERTOS_SMP TEST_ASSERT_EQUAL(1 << cur_core_num, vTaskCoreAffinityGet(NULL)); #else TEST_ASSERT_EQUAL(cur_core_num, xTaskGetAffinity(NULL)); #endif +#endif // !CONFIG_FREERTOS_UNICORE // Reenable scheduling/preemption #if CONFIG_FREERTOS_SMP vTaskPreemptionEnable(NULL);