Added uxTaskGetStackHighWaterMark2(), which is the same as uxTaskGetStackHighWaterMark() other than the return type.

Allows the task name parameter passed into xTaskCreate() to be NULL.
This commit is contained in:
Richard Barry 2018-09-30 21:50:05 +00:00
parent e3dc5e934b
commit c6de0001fa
14 changed files with 140 additions and 27 deletions

View file

@ -114,6 +114,7 @@ to exclude the API function. */
#define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
/* Cortex-M specific definitions. */ /* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS

View file

@ -178,7 +178,7 @@
<DebugFlag> <DebugFlag>
<trace>0</trace> <trace>0</trace>
<periodic>1</periodic> <periodic>1</periodic>
<aLwin>1</aLwin> <aLwin>0</aLwin>
<aCover>0</aCover> <aCover>0</aCover>
<aSer1>0</aSer1> <aSer1>0</aSer1>
<aSer2>0</aSer2> <aSer2>0</aSer2>

View file

@ -766,6 +766,7 @@ static void prvTaskToDelete( void *pvParameters )
/* For code coverage test purposes it is deleted by the Idle task. */ /* For code coverage test purposes it is deleted by the Idle task. */
configASSERT( uxTaskGetStackHighWaterMark( NULL ) > 0 ); configASSERT( uxTaskGetStackHighWaterMark( NULL ) > 0 );
configASSERT( uxTaskGetStackHighWaterMark2( NULL ) > 0 );
vTaskSuspend( NULL ); vTaskSuspend( NULL );
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -1057,7 +1058,7 @@ void vApplicationMallocFailedHook( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
static void prvTimerCallback( TaskHandle_t xExpiredTimer ) static void prvTimerCallback( TimerHandle_t xExpiredTimer )
{ {
uint32_t ulCount; uint32_t ulCount;

View file

@ -729,7 +729,9 @@ TaskHandle_t xCreatedTask;
/* The variable that will hold the TCB of tasks created by this function. See /* The variable that will hold the TCB of tasks created by this function. See
the comments above the declaration of the xCreatorTaskTCBBuffer variable for 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; StaticTask_t xTCBBuffer;
/* This buffer that will be used as the stack of tasks created by this function. /* This buffer that will be used as the stack of tasks created by this function.

View file

@ -104,6 +104,7 @@ functions anyway. */
#define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1 #define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_uxTaskGetStackHighWaterMark2 1
#define INCLUDE_xTaskGetSchedulerState 1 #define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 #define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
#define INCLUDE_xTaskGetIdleTaskHandle 1 #define INCLUDE_xTaskGetIdleTaskHandle 1

View file

@ -381,6 +381,11 @@ const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff;
xReturn = pdFAIL; 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, /* 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. */ which in the case of the idle task should be Read. */
xTimerTask = xTimerGetTimerDaemonTaskHandle(); xTimerTask = xTimerGetTimerDaemonTaskHandle();
@ -408,6 +413,10 @@ const uint32_t ulRunTimeTollerance = ( uint32_t ) 0xfff;
{ {
xReturn = pdFAIL; 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 /* Attempting to abort a delay in the idle task should be guaranteed to
fail as the idle task should never block. */ fail as the idle task should never block. */

View file

@ -201,7 +201,7 @@ int main_full( void )
vStartDynamicPriorityTasks(); vStartDynamicPriorityTasks();
vStartQueueSetTasks(); vStartQueueSetTasks();
vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY ); 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(); vStartEventGroupTasks();
vStartInterruptSemaphoreTasks(); vStartInterruptSemaphoreTasks();
vStartQueueSetPollingTask(); vStartQueueSetPollingTask();

View file

@ -156,6 +156,10 @@ extern "C" {
#define INCLUDE_uxTaskGetStackHighWaterMark 0 #define INCLUDE_uxTaskGetStackHighWaterMark 0
#endif #endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark2
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
#endif
#ifndef INCLUDE_eTaskGetState #ifndef INCLUDE_eTaskGetState
#define INCLUDE_eTaskGetState 0 #define INCLUDE_eTaskGetState 0
#endif #endif

View file

@ -61,6 +61,7 @@ UBaseType_t MPU_uxTaskGetNumberOfTasks( void );
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery );
TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery );
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask );
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue );

View file

@ -67,6 +67,7 @@ only for ports that are using the MPU. */
#define pcTaskGetName MPU_pcTaskGetName #define pcTaskGetName MPU_pcTaskGetName
#define xTaskGetHandle MPU_xTaskGetHandle #define xTaskGetHandle MPU_xTaskGetHandle
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer

View file

@ -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 * 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. * 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. * @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. * 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; UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
/**
* task.h
* <PRE>configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );</PRE>
*
* 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 /* 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, 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 so the following two prototypes will cause a compilation error. This can be

View file

@ -420,6 +420,19 @@ BaseType_t xRunningPrivileged = xPortRaisePrivilege();
#endif #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 ) #if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void )
{ {

View file

@ -131,7 +131,7 @@
STORE x29, 28 * REGBYTES(sp) STORE x29, 28 * REGBYTES(sp)
STORE x30, 29 * REGBYTES(sp) STORE x30, 29 * REGBYTES(sp)
STORE x31, 30 * REGBYTES(sp) STORE x31, 30 * REGBYTES(sp)
/* Store current stackpointer in task control block (TCB) */ /* Store current stackpointer in task control block (TCB) */
LOAD t0, pxCurrentTCB //pointer LOAD t0, pxCurrentTCB //pointer
STORE sp, 0x0(t0) STORE sp, 0x0(t0)

View file

@ -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 /* 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 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. */ 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 #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1
#else #else
#define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 #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 * This function determines the 'high water mark' of the task stack by
* determining how much of the stack remains at the original preset value. * 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; static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
@ -861,8 +861,6 @@ UBaseType_t x;
uxPriority &= ~portPRIVILEGE_BIT; uxPriority &= ~portPRIVILEGE_BIT;
#endif /* portUSING_MPU_WRAPPERS == 1 */ #endif /* portUSING_MPU_WRAPPERS == 1 */
configASSERT( pcName );
/* Avoid dependency on memset() if it is not required. */ /* Avoid dependency on memset() if it is not required. */
#if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )
{ {
@ -905,26 +903,35 @@ UBaseType_t x;
#endif /* portSTACK_GROWTH */ #endif /* portSTACK_GROWTH */
/* Store the task name in the TCB. */ /* 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 ]; for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
{
pxNewTCB->pcTaskName[ x ] = pcName[ x ];
/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than /* 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 configMAX_TASK_NAME_LEN characters just in case the memory after the
string is not accessible (extremely unlikely). */ string is not accessible (extremely unlikely). */
if( pcName[ x ] == ( char ) 0x00 ) if( pcName[ x ] == ( char ) 0x00 )
{ {
break; break;
} }
else else
{ {
mtCOVERAGE_TEST_MARKER(); 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';
}
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;
} }
/* 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';
/* This is used as an array index so must ensure it's not too large. First /* This is used as an array index so must ensure it's not too large. First
remove the privilege bit if one is present. */ remove the privilege bit if one is present. */
@ -3686,7 +3693,7 @@ static void prvCheckTasksWaitingTermination( void )
#endif /* configUSE_TRACE_FACILITY */ #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 ) static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
{ {
@ -3703,7 +3710,47 @@ static void prvCheckTasksWaitingTermination( void )
return ( configSTACK_DEPTH_TYPE ) ulCount; 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 ) #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )