Search code examples
embeddedarmmicrocontrollerrtoscortex-m

Canonical way(s) of determining system time in a microcontroller


Every so often I start a bare metal microcontroller project and end up implementing a system time measurement using a random timer unit.

I am working with ARM Cortex-M devices for a (albeit short) while now and typically used the SysTick ("System Tick") interrupt to create a 1ms resolution timer. It recently stumbled over a post that suggested chaining two Programmable Interrupt Timers (on a Kinetis KL25Z device) in order to create an interrupt-less 32bit millisecond timer, however sacrificing two PIT interrupts which may come in handy later on.

So I was wondering if there are some (sort of) canonical ways to determine the system time on a microcontroller - preferrably for Kinetis KL2xZ devices as I currently work with these, but not necessarily so.


Solution

  • The canonical method as you put it is exactly as you have done - using systick. That is the single timer device defined by the Cortex-M architecture; any other timer hardware is external to the core and vendor specific.

    Some parts (STM32F2 for example) include 32 bit timer/counter hardware, so you would not need to chain two.

    The best approach is to abstract timer services by defining a generic timer API that you implement for all parts you need so that the application layer is identical for all parts. For example in this case you might simply implement the standard library clock() function and define CLOCKS_PER_SEC.

    If you are using two free-running cascaded timers, you must ensure high/low word consistency when combining the two counter values:

    #include <time.h>
    
    clock_t clock( void )
    {
        uint16_t low_word = 0 ;
        uint16_t hi_word = 0 ;
    
        do
        {
            hi_word = readTimerH() ; 
            lo_word = readTimerL() ;
    
        } while( hi_word != readTimerH() ) ;
    
        return (clock_t)(hi_word << 16 | lo_word) ;
    }