Run Time Statistics
Click to enlarge
FreeRTOS can optionally collect information on the amount of processing time that has been used by each task.
The vTaskGetRunTimeStats() API function can then be used to present this information in a tabular format, as
shown on the right.
Two values are given for each task:
- Abs Time (absolute time)
This is the total ‘time’ that the task has actually been executing (the total time that the task has been
in the Running state). It is up to the user to select a suitable time base for their application.
- % Time (percentage time)
This shows essentially the same information but as a percentage of the total processing time rather than as an
Configuration and Usage
Three macros are required. These can be defined in FreeRTOSConfig.h.
The vTaskGetRunTimeStats() API function is used to retrieve the gathered statistics.
Collection of run time statistics is enabled by #defining configGENERATE_RUN_TIME_STATS as 1.
Once this has been set the other two macros must also be defined to achieve a successful
The run time statistics time base needs to have a higher resolution than the tick interrupt –
otherwise the statistics may be too inaccurate to be truly useful. It is recommended to make
the time base between 10 and 100 times faster than the tick interrupt. The faster the time
base the more accurate the statistics will be – but also the sooner the timer value will overflow.
If configGENERATE_RUN_TIME_STATS is defined as 1 then the RTOS kernel will automatically call
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() as it is started (it is called from within the
vTaskStartScheduler() API function). It is intended that the application designer uses the
macro to configure a suitable time base. Some examples are provided below.
This macro should just return the current ‘time’, as configured by portCONFIGURE_TIMER_FOR_RUN_TIME_STATS().
Again some examples are provided below.
[Amongst many others] The LPC17xx LPCXpresso
and the LM3Sxxxx Eclipse web server demo applications are configured to generate run time stats.
The LM3Sxxxx Eclipse demo application already includes a 20KHz timer test. The interrupt handler was updated to simply
increment a variable called ulHighFrequencyTimerTicks each time it executed. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
simply sets this variable to 0 and portGET_RUN_TIME_COUNTER_VALUE() returns its value. To implement this the following
few lines were added to FreeRTOSConfig.h:
extern volatile unsigned long ulHighFrequencyTimerTicks;
/* ulHighFrequencyTimerTicks is already being incremented at 20KHz. Just set
its value back to 0. */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks
The LPC17xx demo application does not include the high frequency interrupt test, so portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
was used to configure the timer 0 peripheral to generate the time base. portGET_RUN_TIME_COUNTER_VALUE() simply returns
the current timer 0 counter value. This was implemented using the following functions and macros.
/* Defined in main.c. */
void vConfigureTimerForRunTimeStats( void )
const unsigned long TCR_COUNT_RESET = 2,
CTCR_CTM_TIMER = 0x00,
TCR_COUNT_ENABLE = 0x01;
/* Power up and feed the timer with a clock. */
PCONP |= 0x02UL;
PCLKSEL0 = (PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
/* Reset Timer 0 */
T0TCR = TCR_COUNT_RESET;
/* Just count up. */
T0CTCR = CTCR_CTM_TIMER;
/* Prescale to a frequency that is good enough to get a decent resolution,
but not too fast so as to overflow all the time. */
T0PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
/* Start the counter. */
T0TCR = TCR_COUNT_ENABLE;
/* Defined in FreeRTOSConfig.h. */
extern void vConfigureTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() T0TC
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.