Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Operating System stop watch type timer

Posted by Chris on October 25, 2011
Hi, I was recently working on some code and wanted to measure how long a function took to execute. I was surprised to find that freeRTOS doesn't offer any functions that help with this need. Seems it would be relatively trivial to add. Essentially by looking at whatever timer the OS uses and then getting how far into the countdown you are as well as the OS ticks you can see how long something has taken. Here is some source code I've written. Is there anything similar that I missed? Would it be useful to include this in freeRTOS? I would imagine that if we put the function somewhere in the OS it would have better access to things like xTickCount.

#define portNVIC_SYSTICK_VALUE ( ( volatile unsigned long *) 0xe000e018 ) // for cortex M3, add to port.c file
#define LONG_COUNT portNVIC_SYSTICK_VALUE + (xTickCount * (( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL))
// When start is TRUE and previously FALSE it will reset and start the timer.
// When start is FALSE and previusly TRUE it will stop the timer and the function then returns clock ticks
int timer(BOOLEAN start)
static BOOLEAN timerRunning = FALSE;
static long counter = 0;

if(timerRunning == FALSE){ // timer is stopped
if(start == TRUE){ // re-set the timer
counter = LONG_COUNT;
return 0;
} else {
return 0;
} else { // timerRunning == TRUE
if(start == TRUE){ // here we just re-set the timer
counter = LONG_COUNT;
return 0;
} else {
return LONG_COUNT - counter;

Here's how to use:
runTime = timer(FALSE);

RE: Operating System stop watch type timer

Posted by Richard on October 25, 2011
The recent run time stats examples on Cortex-M3 parts use the sys tick value. For example (this code is not necessarily bullet proof!):

unsigned long ulMainGetRunTimeCounterValue( void )
unsigned long ulSysTickCounts, ulTickCount, ulReturn;
const unsigned long ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
volatile unsigned long * const pulCurrentSysTickCount = ( ( volatile unsigned long *) 0xe000e018 );
volatile unsigned long * const pulInterruptCTRLState = ( ( volatile unsigned long *) 0xe000ed04 );
const unsigned long ulSysTickPendingBit = 0x04000000UL;

/* NOTE: There are potentially race conditions here. However, it is used
anyway to keep the examples simple, and to avoid reliance on a separate
timer peripheral. */

/* The SysTick is a down counter. How many clocks have passed since it was
last reloaded? */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;

/* How many times has it overflowed? */
ulTickCount = xTaskGetTickCountFromISR();

/* Is there a SysTick interrupt pending? */
if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL )
/* There is a SysTick interrupt pending, so the SysTick has overflowed
but the tick count not yet incremented. */

/* Read the SysTick again, as the overflow might have occurred since
it was read last. */
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;

/* Convert the tick count into tenths of a millisecond. THIS ASSUMES
configTICK_RATE_HZ is 1000! */
ulReturn = ( ulTickCount * 10UL ) ;

/* Add on the number of tenths of a millisecond that have passed since the
tick count last got updated. */
ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond );

return ulReturn;

That is very non-portable though, considering there are 28 cores supported.

If you just want millisecond resolution, and the tick interrupt is set to 1Khz, you can use xTaskGetTickCount() to return the current tick count value.


RE: Operating System stop watch type timer

Posted by Chris on October 26, 2011
I was hoping for anything from less than micro seconds to 100s of milliseconds. I agree using xTaskGetTickCount is a little cleaner than xTickCount depending on which module this function would be compiled from.

So sounds like you're saying neither pulCurrentSysTickCount or my portNVIC_SYSTICK_VALUE are defined in any of those other ports? If it was defined it seems what I have could be fairly portable.

The other obvious limitation is that if the code being timed was interrupted by other tasks then all bets are off.

[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS v10.2.0 is available for immediate download. MIT licensed, and including RISC-V and ARMv8-M (Cortex-M33) demos.

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


FreeRTOS and other embedded software careers at AWS.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Cadence Tensilica Cortes

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers





STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner