The first column is the task name.
The second column is the amount of time the task has spent in the Running state as an
absolute value. See the description of ulRunTimeCounter in Table 56.
The third column is the amount of time the task has spent in the Running state as a percentage of the total time since the target was booted. The total of the displayed percentage times will normally be less than the expected 100% because statistics are collected and calculated using integer calculations that round down to the nearest integer value.
Figure 89 Example output generated by vTaskGetRunTimeStats()
Generating and Displaying Run-Time Statistics, a Worked Example
This example uses a hypothetical 16-bit timer to generate a 32-bit run-time statistics clock.
The counter is configured to generate an interrupt each time the 16-bit value reaches its maximum value—effectively creating an overflow interrupt. The interrupt service routine counts the number of overflow occurrences.
The 32-bit value is created by using the count of overflow occurrences as the two most significant bytes of the 32-bit value, and the current 16-bit counter value as the least significant
two bytes of the 32-bit value. Pseudo code for the interrupt service routine is shown in Listing
170.
345
161204 Pre-release for FreeRTOS V8.x.x. See http://www.FreeRTOS.org/FreeRTOS-V9.html
for information about FreeRTOS
V9.x.x. Use http://www.FreeRTOS.org/contact to provide feedback, corrections, and check for updates.
void TimerOverflowInterruptHandler( void )
{
/* Just count the number of interrupts. */
ulOverflowCount++;
/* Clear the interrupt. */
ClearTimerInterrupt();
}
Listing 170. 16-bit timer overflow interrupt handler used to count timer overflows
Listing 171 shows the lines added to FreeRTOSConfig.h to enable the collection of run-time
statistics.
/* Set configGENERATE_RUN_TIME_STATS to 1 to enable collection of run-time statistics. When this is done, both portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() or portALT_GET_RUN_TIME_COUNTER_VALUE(x) must also be defined. */
#define configGENERATE_RUN_TIME_STATS 1
/* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() is defined to call the function that sets up the hypothetical 16-bit timer (the function ’s implementation is not shown). */ void vSetupTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vSetupTimerForRunTimeStats()
/* portALT_GET_RUN_TIME_COUNTER_VALUE() is defined to set its parameter to the current run-time counter/time value. The returned time value is 32-bits long, and is formed by shifting the count of 16-bit timer overflows into the top two bytes of a
32-bit number, then bitwise ORing the result with the current 16-bit counter value. */
#define portALT_GET_RUN_TIME_COUNTER_VALUE( ulCountValue ) \
{ \
extern volatile unsigned long ulOverflowCount; \
\
/* Disconnect the clock from the counter so it does not change \ while its value is being used. */ \
PauseTimer(); \
\
/* The number of overflows is shifted into the most significant \ two bytes of the returned 32-bit value. */ \
ulCountValue = ( ulOverflowCount << 16UL ); \
\
/* The current counter value is used as the least significant \ two bytes of the returned 32-bit value. */ \
ulCountValue |= ( unsigned long ) ReadTimerCount(); \
\
/* Reconnect the clock to the counter. */ \
ResumeTimer(); \
}
Listing 171. Macros added to FreeRTOSConfig.h to enable the collection of run-time statistics
The task shown in Listing 172 prints out the collected run-time statistics every 5 seconds.
346
/* For clarity, calls to fflush() have been omitted from this code listing. */ static void prvStatsTask( void *pvParameters )
{
TickType_t xLastExecutionTime;
/* The buffer used to hold the formatted run-time statistics text needs to be quite large. It is therefore declared static to ensure it is not allocated on the task stack. This makes this function non re-entrant. */ static signed char cStringBuffer[ 512 ];
/* The task will run every 5 seconds. */ const TickType_t xBlockPeriod = pdMS_TO_TICKS( 5000 );
/* Initialize xLastExecutionTime to the current time. This is the only time this
variable needs to be written to explicitly. Afterwards it is updated internally
within the vTaskDelayUntil() API function. */
xLastExecutionTime = xTaskGetTickCount();
/* As per most tasks, this task is implemented in an infinite loop. */
for( ;; )
{
/* Wait until it is time to run this task again. */
vTaskDelayUntil( &xLastExecutionTime, xBlockPeriod );
/* Generate a text table from the run-time stats. This must fit into the
cStringBuffer array. */
vTaskGetRunTimeStats( cStringBuffer );
/* Print out column headings for the run-time stats table. */
printf( "\nTask\t\tAbs\t\t\t%%\n" );
printf( "-------------------------------------------------------------\n" );
/* Print out the run-time stats themselves. The table of data contains
multiple lines, so the vPrintMultipleLines() function is called instead of
calling printf() directly. vPrintMultipleLines() simply calls printf() on
each line individually, to ensure the line buffering works as expected. */
vPrintMultipleLines( cStringBuffer );
}
}
Listing 172. The task that prints out the collected run-time statistics
347