Merge branch 'main' into main

This commit is contained in:
Joseph Julicher 2023-09-26 14:09:05 -07:00 committed by GitHub
commit c74fcc1f89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 328 additions and 64 deletions

View file

@ -2154,20 +2154,20 @@
#define traceRETURN_vTaskExitCriticalFromISR() #define traceRETURN_vTaskExitCriticalFromISR()
#endif #endif
#ifndef traceENTER_vTaskList #ifndef traceENTER_vTaskListTasks
#define traceENTER_vTaskList( pcWriteBuffer ) #define traceENTER_vTaskListTasks( pcWriteBuffer, uxBufferLength )
#endif #endif
#ifndef traceRETURN_vTaskList #ifndef traceRETURN_vTaskListTasks
#define traceRETURN_vTaskList() #define traceRETURN_vTaskListTasks()
#endif #endif
#ifndef traceENTER_vTaskGetRunTimeStats #ifndef traceENTER_vTaskGetRunTimeStatistics
#define traceENTER_vTaskGetRunTimeStats( pcWriteBuffer ) #define traceENTER_vTaskGetRunTimeStatistics( pcWriteBuffer, uxBufferLength )
#endif #endif
#ifndef traceRETURN_vTaskGetRunTimeStats #ifndef traceRETURN_vTaskGetRunTimeStatistics
#define traceRETURN_vTaskGetRunTimeStats() #define traceRETURN_vTaskGetRunTimeStatistics()
#endif #endif
#ifndef traceENTER_uxTaskResetEventItemValue #ifndef traceENTER_uxTaskResetEventItemValue
@ -2686,6 +2686,10 @@
#endif #endif
#endif #endif
#ifndef configSTATS_BUFFER_MAX_LENGTH
#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF
#endif
#ifndef configSTACK_DEPTH_TYPE #ifndef configSTACK_DEPTH_TYPE
/* Defaults to uint16_t for backward compatibility, but can be overridden /* Defaults to uint16_t for backward compatibility, but can be overridden

View file

@ -2074,6 +2074,60 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize, const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION; configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION;
/**
* task. h
* @code{c}
* void vTaskListTasks( char *pcWriteBuffer, size_t uxBufferLength );
* @endcode
*
* configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must
* both be defined as 1 for this function to be available. See the
* configuration section of the FreeRTOS.org website for more information.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Lists all the current tasks, along with their current state and stack
* usage high water mark.
*
* Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
* suspended ('S').
*
* PLEASE NOTE:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskListTasks() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that displays task:
* names, states, priority, stack usage and task number.
* Stack usage specified as the number of unused StackType_t words stack can hold
* on top of stack - not the number of bytes.
*
* vTaskListTasks() has a dependency on the snprintf() C library function that might
* bloat the code size, use a lot of stack, and provide different results on
* different platforms. An alternative, tiny, third party, and limited
* functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly through a
* call to vTaskListTasks().
*
* @param pcWriteBuffer A buffer into which the above mentioned details
* will be written, in ASCII form. This buffer is assumed to be large
* enough to contain the generated report. Approximately 40 bytes per
* task should be sufficient.
*
* @param uxBufferLength Length of the pcWriteBuffer.
*
* \defgroup vTaskListTasks vTaskListTasks
* \ingroup TaskUtils
*/
void vTaskListTasks( char * pcWriteBuffer,
size_t uxBufferLength ) PRIVILEGED_FUNCTION;
/** /**
* task. h * task. h
* @code{c} * @code{c}
@ -2084,6 +2138,11 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* both be defined as 1 for this function to be available. See the * both be defined as 1 for this function to be available. See the
* configuration section of the FreeRTOS.org website for more information. * configuration section of the FreeRTOS.org website for more information.
* *
* WARN: This function assumes that the pcWriteBuffer is of length
* configSTATS_BUFFER_MAX_LENGTH. This function is there only for
* backward compatibility. New applications are recommended to
* use vTaskListTasks and supply the length of the pcWriteBuffer explicitly.
*
* NOTE 1: This function will disable interrupts for its duration. It is * NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid. * not intended for normal application runtime use but as a debug aid.
* *
@ -2104,10 +2163,10 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* Stack usage specified as the number of unused StackType_t words stack can hold * Stack usage specified as the number of unused StackType_t words stack can hold
* on top of stack - not the number of bytes. * on top of stack - not the number of bytes.
* *
* vTaskList() has a dependency on the sprintf() C library function that might * vTaskList() has a dependency on the snprintf() C library function that might
* bloat the code size, use a lot of stack, and provide different results on * bloat the code size, use a lot of stack, and provide different results on
* different platforms. An alternative, tiny, third party, and limited * different platforms. An alternative, tiny, third party, and limited
* functionality implementation of sprintf() is provided in many of the * functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!). * printf-stdarg.c does not provide a full snprintf() implementation!).
* *
@ -2123,7 +2182,66 @@ UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
* \defgroup vTaskList vTaskList * \defgroup vTaskList vTaskList
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #define vTaskList( pcWriteBuffer ) vTaskListTasks( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH )
/**
* task. h
* @code{c}
* void vTaskGetRunTimeStatistics( char *pcWriteBuffer, size_t uxBufferLength );
* @endcode
*
* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS
* must both be defined as 1 for this function to be available. The application
* must also then provide definitions for
* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()
* to configure a peripheral timer/counter and return the timers current count
* value respectively. The counter should be at least 10 times the frequency of
* the tick count.
*
* NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid.
*
* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total
* accumulated execution time being stored for each task. The resolution
* of the accumulated time value depends on the frequency of the timer
* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.
* Calling vTaskGetRunTimeStatistics() writes the total execution time of each
* task into a buffer, both as an absolute count value and as a percentage
* of the total system execution time.
*
* NOTE 2:
*
* This function is provided for convenience only, and is used by many of the
* demo applications. Do not consider it to be part of the scheduler.
*
* vTaskGetRunTimeStatistics() calls uxTaskGetSystemState(), then formats part of
* the uxTaskGetSystemState() output into a human readable table that displays the
* amount of time each task has spent in the Running state in both absolute and
* percentage terms.
*
* vTaskGetRunTimeStatistics() has a dependency on the snprintf() C library function
* that might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, and
* limited functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!).
*
* It is recommended that production systems call uxTaskGetSystemState() directly
* to get access to raw stats data, rather than indirectly through a call to
* vTaskGetRunTimeStatistics().
*
* @param pcWriteBuffer A buffer into which the execution times will be
* written, in ASCII form. This buffer is assumed to be large enough to
* contain the generated report. Approximately 40 bytes per task should
* be sufficient.
*
* @param uxBufferLength Length of the pcWriteBuffer.
*
* \defgroup vTaskGetRunTimeStatistics vTaskGetRunTimeStatistics
* \ingroup TaskUtils
*/
void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
size_t uxBufferLength ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
/** /**
* task. h * task. h
@ -2139,6 +2257,12 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* value respectively. The counter should be at least 10 times the frequency of * value respectively. The counter should be at least 10 times the frequency of
* the tick count. * the tick count.
* *
* WARN: This function assumes that the pcWriteBuffer is of length
* configSTATS_BUFFER_MAX_LENGTH. This function is there only for
* backward compatiblity. New applications are recommended to use
* vTaskGetRunTimeStatistics and supply the length of the pcWriteBuffer
* explicitly.
*
* NOTE 1: This function will disable interrupts for its duration. It is * NOTE 1: This function will disable interrupts for its duration. It is
* not intended for normal application runtime use but as a debug aid. * not intended for normal application runtime use but as a debug aid.
* *
@ -2160,10 +2284,10 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* amount of time each task has spent in the Running state in both absolute and * amount of time each task has spent in the Running state in both absolute and
* percentage terms. * percentage terms.
* *
* vTaskGetRunTimeStats() has a dependency on the sprintf() C library function * vTaskGetRunTimeStats() has a dependency on the snprintf() C library function
* that might bloat the code size, use a lot of stack, and provide different * that might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, and * results on different platforms. An alternative, tiny, third party, and
* limited functionality implementation of sprintf() is provided in many of the * limited functionality implementation of snprintf() is provided in many of the
* FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note
* printf-stdarg.c does not provide a full snprintf() implementation!). * printf-stdarg.c does not provide a full snprintf() implementation!).
* *
@ -2179,7 +2303,7 @@ void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unquali
* \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats
* \ingroup TaskUtils * \ingroup TaskUtils
*/ */
void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ #define vTaskGetRunTimeStats( pcWriteBuffer ) vTaskGetRunTimeStatistics( pcWriteBuffer, configSTATS_BUFFER_MAX_LENGTH )
/** /**
* task. h * task. h

236
tasks.c
View file

@ -719,6 +719,32 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
extern void vApplicationMinimalIdleHook( void ); extern void vApplicationMinimalIdleHook( void );
#endif /* #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */ #endif /* #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
/*
* Convert the snprintf return value to the number of characters
* written. The following are the possible cases:
*
* 1. The buffer supplied to snprintf is large enough to hold the
* generated string. The return value in this case is the number
* of characters actually written, not counting the terminating
* null character.
* 2. The buffer supplied to snprintf is NOT large enough to hold
* the generated string. The return value in this case is the
* number of characters that would have been written if the
* buffer had been sufficiently large, not counting the
* terminating null character.
* 3. Encoding error. The return value in this case is a negative
* number.
*
* From 1 and 2 above ==> Only when the return value is non-negative
* and less than the supplied buffer length, the string has been
* completely written.
*/
static size_t prvSnprintfReturnValueToCharsWritten( int iSnprintfReturnValue,
size_t n );
#endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configNUMBER_OF_CORES > 1 ) #if ( configNUMBER_OF_CORES > 1 )
@ -1914,6 +1940,39 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */ #endif /* #if ( configNUMBER_OF_CORES == 1 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
static size_t prvSnprintfReturnValueToCharsWritten( int iSnprintfReturnValue,
size_t n )
{
size_t uxCharsWritten;
if( iSnprintfReturnValue < 0 )
{
/* Encoding error - Return 0 to indicate that nothing
* was written to the buffer. */
uxCharsWritten = 0;
}
else if( iSnprintfReturnValue >= ( int ) n )
{
/* This is the case when the supplied buffer is not
* large to hold the generated string. Return the
* number of characters actually written without
* counting the terminating NULL character. */
uxCharsWritten = n - 1;
}
else
{
/* Complete string was written to the buffer. */
uxCharsWritten = ( size_t ) iSnprintfReturnValue;
}
return uxCharsWritten;
}
#endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
/*-----------------------------------------------------------*/
#if ( INCLUDE_vTaskDelete == 1 ) #if ( INCLUDE_vTaskDelete == 1 )
void vTaskDelete( TaskHandle_t xTaskToDelete ) void vTaskDelete( TaskHandle_t xTaskToDelete )
@ -6812,13 +6871,18 @@ static void prvResetNextTaskUnblockTime( void )
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
void vTaskList( char * pcWriteBuffer ) void vTaskListTasks( char * pcWriteBuffer,
size_t uxBufferLength )
{ {
TaskStatus_t * pxTaskStatusArray; TaskStatus_t * pxTaskStatusArray;
size_t uxConsumedBufferLength = 0;
size_t uxCharsWrittenBySnprintf;
int iSnprintfReturnValue;
BaseType_t xOutputBufferFull = pdFALSE;
UBaseType_t uxArraySize, x; UBaseType_t uxArraySize, x;
char cStatus; char cStatus;
traceENTER_vTaskList( pcWriteBuffer ); traceENTER_vTaskListTasks( pcWriteBuffer, uxBufferLength );
/* /*
* PLEASE NOTE: * PLEASE NOTE:
@ -6827,23 +6891,23 @@ static void prvResetNextTaskUnblockTime( void )
* of the demo applications. Do not consider it to be part of the * of the demo applications. Do not consider it to be part of the
* scheduler. * scheduler.
* *
* vTaskList() calls uxTaskGetSystemState(), then formats part of the * vTaskListTasks() calls uxTaskGetSystemState(), then formats part of the
* uxTaskGetSystemState() output into a human readable table that * uxTaskGetSystemState() output into a human readable table that
* displays task: names, states, priority, stack usage and task number. * displays task: names, states, priority, stack usage and task number.
* Stack usage specified as the number of unused StackType_t words stack can hold * Stack usage specified as the number of unused StackType_t words stack can hold
* on top of stack - not the number of bytes. * on top of stack - not the number of bytes.
* *
* vTaskList() has a dependency on the sprintf() C library function that * vTaskListTasks() has a dependency on the snprintf() C library function that
* might bloat the code size, use a lot of stack, and provide different * might bloat the code size, use a lot of stack, and provide different
* results on different platforms. An alternative, tiny, third party, * results on different platforms. An alternative, tiny, third party,
* and limited functionality implementation of sprintf() is provided in * and limited functionality implementation of snprintf() is provided in
* many of the FreeRTOS/Demo sub-directories in a file called * many of the FreeRTOS/Demo sub-directories in a file called
* printf-stdarg.c (note printf-stdarg.c does not provide a full * printf-stdarg.c (note printf-stdarg.c does not provide a full
* snprintf() implementation!). * snprintf() implementation!).
* *
* It is recommended that production systems call uxTaskGetSystemState() * It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly * directly to get access to raw stats data, rather than indirectly
* through a call to vTaskList(). * through a call to vTaskListTasks().
*/ */
@ -6865,7 +6929,7 @@ static void prvResetNextTaskUnblockTime( void )
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );
/* Create a human readable table from the binary data. */ /* Create a human readable table from the binary data. */
for( x = 0; x < uxArraySize; x++ ) for( x = 0; ( x < uxArraySize ) && ( xOutputBufferFull == pdFALSE ); x++ )
{ {
switch( pxTaskStatusArray[ x ].eCurrentState ) switch( pxTaskStatusArray[ x ].eCurrentState )
{ {
@ -6896,13 +6960,43 @@ static void prvResetNextTaskUnblockTime( void )
break; break;
} }
/* Write the task name to the string, padding with spaces so it /* Is there enough space in the buffer to hold task name? */
* can be printed in tabular form more easily. */ if( ( uxConsumedBufferLength + configMAX_TASK_NAME_LEN ) <= uxBufferLength )
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); {
/* Write the task name to the string, padding with spaces so it
* can be printed in tabular form more easily. */
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
/* Do not count the terminating null character. */
uxConsumedBufferLength = uxConsumedBufferLength + ( configMAX_TASK_NAME_LEN - 1 );
/* Write the rest of the string. */ /* Is there space left in the buffer? -1 is done because snprintf
sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ * writes a terminating null character. So we are essentially
pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ * checking if the buffer has space to write at least one non-null
* character. */
if( uxConsumedBufferLength < ( uxBufferLength - 1 ) )
{
/* Write the rest of the string. */
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%c\t%u\t%u\t%u\r\n",
cStatus,
( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority,
( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark,
( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
uxCharsWrittenBySnprintf = prvSnprintfReturnValueToCharsWritten( iSnprintfReturnValue, uxBufferLength - uxConsumedBufferLength );
uxConsumedBufferLength += uxCharsWrittenBySnprintf;
pcWriteBuffer += uxCharsWrittenBySnprintf; /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */
}
else
{
xOutputBufferFull = pdTRUE;
}
}
else
{
xOutputBufferFull = pdTRUE;
}
} }
/* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION
@ -6914,7 +7008,7 @@ static void prvResetNextTaskUnblockTime( void )
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
traceRETURN_vTaskList(); traceRETURN_vTaskListTasks();
} }
#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ #endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */
@ -6922,13 +7016,18 @@ static void prvResetNextTaskUnblockTime( void )
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) ) #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) )
void vTaskGetRunTimeStats( char * pcWriteBuffer ) void vTaskGetRunTimeStatistics( char * pcWriteBuffer,
size_t uxBufferLength )
{ {
TaskStatus_t * pxTaskStatusArray; TaskStatus_t * pxTaskStatusArray;
size_t uxConsumedBufferLength = 0;
size_t uxCharsWrittenBySnprintf;
int iSnprintfReturnValue;
BaseType_t xOutputBufferFull = pdFALSE;
UBaseType_t uxArraySize, x; UBaseType_t uxArraySize, x;
configRUN_TIME_COUNTER_TYPE ulTotalTime, ulStatsAsPercentage; configRUN_TIME_COUNTER_TYPE ulTotalTime, ulStatsAsPercentage;
traceENTER_vTaskGetRunTimeStats( pcWriteBuffer ); traceENTER_vTaskGetRunTimeStatistics( pcWriteBuffer, uxBufferLength );
/* /*
* PLEASE NOTE: * PLEASE NOTE:
@ -6937,22 +7036,22 @@ static void prvResetNextTaskUnblockTime( void )
* of the demo applications. Do not consider it to be part of the * of the demo applications. Do not consider it to be part of the
* scheduler. * scheduler.
* *
* vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part * vTaskGetRunTimeStatistics() calls uxTaskGetSystemState(), then formats part
* of the uxTaskGetSystemState() output into a human readable table that * of the uxTaskGetSystemState() output into a human readable table that
* displays the amount of time each task has spent in the Running state * displays the amount of time each task has spent in the Running state
* in both absolute and percentage terms. * in both absolute and percentage terms.
* *
* vTaskGetRunTimeStats() has a dependency on the sprintf() C library * vTaskGetRunTimeStatistics() has a dependency on the snprintf() C library
* function that might bloat the code size, use a lot of stack, and * function that might bloat the code size, use a lot of stack, and
* provide different results on different platforms. An alternative, * provide different results on different platforms. An alternative,
* tiny, third party, and limited functionality implementation of * tiny, third party, and limited functionality implementation of
* sprintf() is provided in many of the FreeRTOS/Demo sub-directories in * snprintf() is provided in many of the FreeRTOS/Demo sub-directories in
* a file called printf-stdarg.c (note printf-stdarg.c does not provide * a file called printf-stdarg.c (note printf-stdarg.c does not provide
* a full snprintf() implementation!). * a full snprintf() implementation!).
* *
* It is recommended that production systems call uxTaskGetSystemState() * It is recommended that production systems call uxTaskGetSystemState()
* directly to get access to raw stats data, rather than indirectly * directly to get access to raw stats data, rather than indirectly
* through a call to vTaskGetRunTimeStats(). * through a call to vTaskGetRunTimeStatistics().
*/ */
/* Make sure the write buffer does not contain a string. */ /* Make sure the write buffer does not contain a string. */
@ -6979,50 +7078,87 @@ static void prvResetNextTaskUnblockTime( void )
if( ulTotalTime > 0UL ) if( ulTotalTime > 0UL )
{ {
/* Create a human readable table from the binary data. */ /* Create a human readable table from the binary data. */
for( x = 0; x < uxArraySize; x++ ) for( x = 0; ( x < uxArraySize ) && ( xOutputBufferFull == pdFALSE ); x++ )
{ {
/* What percentage of the total run time has the task used? /* What percentage of the total run time has the task used?
* This will always be rounded down to the nearest integer. * This will always be rounded down to the nearest integer.
* ulTotalRunTime has already been divided by 100. */ * ulTotalRunTime has already been divided by 100. */
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
/* Write the task name to the string, padding with /* Is there enough space in the buffer to hold task name? */
* spaces so it can be printed in tabular form more if( ( uxConsumedBufferLength + configMAX_TASK_NAME_LEN ) <= uxBufferLength )
* easily. */
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
if( ulStatsAsPercentage > 0UL )
{ {
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED /* Write the task name to the string, padding with
* spaces so it can be printed in tabular form more
* easily. */
pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName );
/* Do not count the terminating null character. */
uxConsumedBufferLength = uxConsumedBufferLength + ( configMAX_TASK_NAME_LEN - 1 );
/* Is there space left in the buffer? -1 is done because snprintf
* writes a terminating null character. So we are essentially
* checking if the buffer has space to write at least one non-null
* character. */
if( uxConsumedBufferLength < ( uxBufferLength - 1 ) )
{ {
sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); if( ulStatsAsPercentage > 0UL )
{
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%lu\t\t%lu%%\r\n",
pxTaskStatusArray[ x ].ulRunTimeCounter,
ulStatsAsPercentage );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
* printf() library can be used. */
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%u\t\t%u%%\r\n",
( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter,
( unsigned int ) ulStatsAsPercentage ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
}
#endif /* ifdef portLU_PRINTF_SPECIFIER_REQUIRED */
}
else
{
/* If the percentage is zero here then the task has
* consumed less than 1% of the total run time. */
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%lu\t\t<1%%\r\n",
pxTaskStatusArray[ x ].ulRunTimeCounter );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
* printf() library can be used. */
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%u\t\t<1%%\r\n",
( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
}
#endif /* ifdef portLU_PRINTF_SPECIFIER_REQUIRED */
}
uxCharsWrittenBySnprintf = prvSnprintfReturnValueToCharsWritten( iSnprintfReturnValue, uxBufferLength - uxConsumedBufferLength );
uxConsumedBufferLength += uxCharsWrittenBySnprintf;
pcWriteBuffer += uxCharsWrittenBySnprintf; /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */
} }
#else else
{ {
/* sizeof( int ) == sizeof( long ) so a smaller xOutputBufferFull = pdTRUE;
* printf() library can be used. */
sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
} }
#endif
} }
else else
{ {
/* If the percentage is zero here then the task has xOutputBufferFull = pdTRUE;
* consumed less than 1% of the total run time. */
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED
{
sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter );
}
#else
{
/* sizeof( int ) == sizeof( long ) so a smaller
* printf() library can be used. */
sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */
}
#endif
} }
pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */
} }
} }
else else
@ -7039,7 +7175,7 @@ static void prvResetNextTaskUnblockTime( void )
mtCOVERAGE_TEST_MARKER(); mtCOVERAGE_TEST_MARKER();
} }
traceRETURN_vTaskGetRunTimeStats(); traceRETURN_vTaskGetRunTimeStatistics();
} }
#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ #endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */