From a3852ccc77c5d8e04cfef0003408dfa5409f6f2f Mon Sep 17 00:00:00 2001 From: rtel Date: Sun, 30 Sep 2018 21:50:05 +0000 Subject: [PATCH] Added uxTaskGetStackHighWaterMark2(), which is the same as uxTaskGetStackHighWaterMark() other than the return type. Allows the task name parameter passed into xTaskCreate() to be NULL. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2586 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../FreeRTOSConfig.h | 1 + .../Keil_Specific/RTOSDemo.uvoptx | 2 +- .../Demo/CORTEX_MPU_Simulator_Keil_GCC/main.c | 3 +- .../Demo/Common/Minimal/StaticAllocation.c | 4 +- FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h | 1 + .../WIN32-MingW/code_coverage_additions.c | 9 ++ FreeRTOS/Demo/WIN32-MingW/main_full.c | 2 +- FreeRTOS/Source/include/FreeRTOS.h | 4 + FreeRTOS/Source/include/mpu_prototypes.h | 1 + FreeRTOS/Source/include/mpu_wrappers.h | 1 + FreeRTOS/Source/include/task.h | 33 +++++++ .../Source/portable/Common/mpu_wrappers.c | 13 +++ .../portable/ThirdParty/GCC/RISC-V/portasm.S | 2 +- FreeRTOS/Source/tasks.c | 91 ++++++++++++++----- 14 files changed, 140 insertions(+), 27 deletions(-) diff --git a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/FreeRTOSConfig.h index ce4ce82a2..e8b04346a 100644 --- a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/FreeRTOSConfig.h @@ -114,6 +114,7 @@ to exclude the API function. */ #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 /* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS diff --git a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/Keil_Specific/RTOSDemo.uvoptx b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/Keil_Specific/RTOSDemo.uvoptx index e07fcd2de..740ec3bbb 100644 --- a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/Keil_Specific/RTOSDemo.uvoptx +++ b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/Keil_Specific/RTOSDemo.uvoptx @@ -178,7 +178,7 @@ 0 1 - 1 + 0 0 0 0 diff --git a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/main.c b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/main.c index 254e51cb7..1ccddbbe7 100644 --- a/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/main.c +++ b/FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/main.c @@ -766,6 +766,7 @@ static void prvTaskToDelete( void *pvParameters ) /* For code coverage test purposes it is deleted by the Idle task. */ configASSERT( uxTaskGetStackHighWaterMark( NULL ) > 0 ); + configASSERT( uxTaskGetStackHighWaterMark2( NULL ) > 0 ); vTaskSuspend( NULL ); } /*-----------------------------------------------------------*/ @@ -1057,7 +1058,7 @@ void vApplicationMallocFailedHook( void ) } /*-----------------------------------------------------------*/ -static void prvTimerCallback( TaskHandle_t xExpiredTimer ) +static void prvTimerCallback( TimerHandle_t xExpiredTimer ) { uint32_t ulCount; diff --git a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c index 328567268..e093467fb 100644 --- a/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c +++ b/FreeRTOS/Demo/Common/Minimal/StaticAllocation.c @@ -729,7 +729,9 @@ TaskHandle_t xCreatedTask; /* The variable that will hold the TCB of tasks created by this function. See the comments above the declaration of the xCreatorTaskTCBBuffer variable for -more information. */ +more information. NOTE: This is not static so relies on the tasks that use it +being deleted before this function returns and deallocates its stack. That will +only be the case if configUSE_PREEMPTION is set to 1. */ StaticTask_t xTCBBuffer; /* This buffer that will be used as the stack of tasks created by this function. diff --git a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h index f70cf1b76..ef07b7609 100644 --- a/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/WIN32-MingW/FreeRTOSConfig.h @@ -104,6 +104,7 @@ functions anyway. */ #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_uxTaskGetStackHighWaterMark2 1 #define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 #define INCLUDE_xTaskGetIdleTaskHandle 1 diff --git a/FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c b/FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c index 739005d5d..5aafe110b 100644 --- a/FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c +++ b/FreeRTOS/Demo/WIN32-MingW/code_coverage_additions.c @@ -381,6 +381,11 @@ const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff; xReturn = pdFAIL; } + if( uxTaskGetStackHighWaterMark2( NULL ) != ( configSTACK_DEPTH_TYPE ) xStatus.usStackHighWaterMark ) + { + xReturn = pdFAIL; + } + /* Now obtain a task status without the high water mark but with the state, which in the case of the idle task should be Read. */ xTimerTask = xTimerGetTimerDaemonTaskHandle(); @@ -408,6 +413,10 @@ const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff; { xReturn = pdFAIL; } + if( uxTaskGetStackHighWaterMark2( xTimerTask ) != ( configSTACK_DEPTH_TYPE ) xStatus.usStackHighWaterMark ) + { + xReturn = pdFAIL; + } /* Attempting to abort a delay in the idle task should be guaranteed to fail as the idle task should never block. */ diff --git a/FreeRTOS/Demo/WIN32-MingW/main_full.c b/FreeRTOS/Demo/WIN32-MingW/main_full.c index be6b32b18..b6f59aafc 100644 --- a/FreeRTOS/Demo/WIN32-MingW/main_full.c +++ b/FreeRTOS/Demo/WIN32-MingW/main_full.c @@ -201,7 +201,7 @@ int main_full( void ) vStartDynamicPriorityTasks(); vStartQueueSetTasks(); vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); - xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvDemoQueueSpaceFunctions, NULL, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); /* Name is null for code coverage. */ vStartEventGroupTasks(); vStartInterruptSemaphoreTasks(); vStartQueueSetPollingTask(); diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index 9ea19416a..9329e0cff 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -156,6 +156,10 @@ extern "C" { #define INCLUDE_uxTaskGetStackHighWaterMark 0 #endif +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 + #define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + #ifndef INCLUDE_eTaskGetState #define INCLUDE_eTaskGetState 0 #endif diff --git a/FreeRTOS/Source/include/mpu_prototypes.h b/FreeRTOS/Source/include/mpu_prototypes.h index b050371e5..9b9492231 100644 --- a/FreeRTOS/Source/include/mpu_prototypes.h +++ b/FreeRTOS/Source/include/mpu_prototypes.h @@ -61,6 +61,7 @@ UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ); void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); diff --git a/FreeRTOS/Source/include/mpu_wrappers.h b/FreeRTOS/Source/include/mpu_wrappers.h index 641c8e63f..96e94ffe4 100644 --- a/FreeRTOS/Source/include/mpu_wrappers.h +++ b/FreeRTOS/Source/include/mpu_wrappers.h @@ -67,6 +67,7 @@ only for ports that are using the MPU. */ #define pcTaskGetName MPU_pcTaskGetName #define xTaskGetHandle MPU_xTaskGetHandle #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer diff --git a/FreeRTOS/Source/include/task.h b/FreeRTOS/Source/include/task.h index 1a5136e8d..a03ff82a6 100644 --- a/FreeRTOS/Source/include/task.h +++ b/FreeRTOS/Source/include/task.h @@ -1413,6 +1413,12 @@ TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /* * a value of 1 means 4 bytes) since the task started. The smaller the returned * number the closer the task has come to overflowing its stack. * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * * @param xTask Handle of the task associated with the stack to be checked. * Set xTask to NULL to check the stack of the calling task. * @@ -1422,6 +1428,33 @@ TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /* */ UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +/** + * task.h + *
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( 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 diff --git a/FreeRTOS/Source/portable/Common/mpu_wrappers.c b/FreeRTOS/Source/portable/Common/mpu_wrappers.c index c48075db1..cb86b793e 100644 --- a/FreeRTOS/Source/portable/Common/mpu_wrappers.c +++ b/FreeRTOS/Source/portable/Common/mpu_wrappers.c @@ -420,6 +420,19 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege(); #endif /*-----------------------------------------------------------*/ +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + configSTACK_DEPTH_TYPE uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + #if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) { diff --git a/FreeRTOS/Source/portable/ThirdParty/GCC/RISC-V/portasm.S b/FreeRTOS/Source/portable/ThirdParty/GCC/RISC-V/portasm.S index 3a2f3fad2..78b22652e 100644 --- a/FreeRTOS/Source/portable/ThirdParty/GCC/RISC-V/portasm.S +++ b/FreeRTOS/Source/portable/ThirdParty/GCC/RISC-V/portasm.S @@ -131,7 +131,7 @@ STORE x29, 28 * REGBYTES(sp) STORE x30, 29 * REGBYTES(sp) STORE x31, 30 * REGBYTES(sp) - + /* Store current stackpointer in task control block (TCB) */ LOAD t0, pxCurrentTCB //pointer STORE sp, 0x0(t0) diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c index f6009fcc7..e494bbcef 100644 --- a/FreeRTOS/Source/tasks.c +++ b/FreeRTOS/Source/tasks.c @@ -100,7 +100,7 @@ changed then the definition of StaticTask_t must also be updated. */ /* If any of the following are set then task stacks are filled with a known value so the high water mark can be determined. If none of the following are set then don't fill the stack so there is no unnecessary dependency on memset. */ -#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 #else #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 @@ -521,7 +521,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseT * This function determines the 'high water mark' of the task stack by * determining how much of the stack remains at the original preset value. */ -#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; @@ -861,8 +861,6 @@ UBaseType_t x; uxPriority &= ~portPRIVILEGE_BIT; #endif /* portUSING_MPU_WRAPPERS == 1 */ - configASSERT( pcName ); - /* Avoid dependency on memset() if it is not required. */ #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) { @@ -905,26 +903,35 @@ UBaseType_t x; #endif /* portSTACK_GROWTH */ /* Store the task name in the TCB. */ - for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + if( pcName != NULL ) { - pxNewTCB->pcTaskName[ x ] = pcName[ x ]; - - /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than - configMAX_TASK_NAME_LEN characters just in case the memory after the - string is not accessible (extremely unlikely). */ - if( pcName[ x ] == ( char ) 0x00 ) - { - break; - } - else + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) { - mtCOVERAGE_TEST_MARKER(); + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } - } - /* Ensure the name string is terminated in the case that the string length - was greater or equal to configMAX_TASK_NAME_LEN. */ - pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + } + else + { + /* The task has not been given a name, so just ensure there is a NULL + terminator when it is read out. */ + pxNewTCB->pcTaskName[ 0 ] = 0x00; + } /* This is used as an array index so must ensure it's not too large. First remove the privilege bit if one is present. */ @@ -3686,7 +3693,7 @@ static void prvCheckTasksWaitingTermination( void ) #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ -#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) { @@ -3703,7 +3710,47 @@ static void prvCheckTasksWaitingTermination( void ) return ( configSTACK_DEPTH_TYPE ) ulCount; } -#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + same except for their return type. Using configSTACK_DEPTH_TYPE allows the + user to determine the return type. It gets around the problem of the value + overflowing on 8-bit types without breaking backward compatibility for + applications that expect an 8-bit return type. */ + configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + configSTACK_DEPTH_TYPE uxReturn; + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are + the same except for their return type. Using configSTACK_DEPTH_TYPE + allows the user to determine the return type. It gets around the + problem of the value overflowing on 8-bit types without breaking + backward compatibility for applications that expect an 8-bit return + type. */ + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ /*-----------------------------------------------------------*/ #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) -- 2.39.5