The SysTick timer is a key component in ARM Cortex-M cores that enables simple timekeeping and basic task scheduling in embedded systems. It provides a simple countdown timer and interrupt generation to support periodic task execution. The SysTick timer is intended for use as a periodic scheduler for a small real-time operating system or superloop RTOS.
Overview of the SysTick Timer
The SysTick timer is a 24-bit countdown timer built into the Cortex-M CPU core that generates interrupts when it reaches zero. It can be configured to generate periodic interrupts at a programmable interval by reloading the timer after it expires. The timer reload value is configured through the SysTick Reload Value Register (SYST_RVR), which allows intervals between 1 and 16,777,216 clock cycles.
In addition to the reload value, there are control registers to enable the timer, generate interrupts on expiration, and monitor the current value. The SysTick Control and Status Register (SYST_CSR) is used to enable the timer, enable interrupts, and monitor counting status. The SysTick Current Value Register (SYST_CVR) can be read to get the current timer value.
When enabled, the SysTick timer counts down from the reload value to zero repeatedly. On expiration, it sets the COUNTFLAG bit in the status register and optionally generates a SysTick exception if enabled. The interrupt allows timed execution of periodic tasks or foreground/background scheduling in a small embedded RTOS.
Using the SysTick Timer
Here are some typical uses of the SysTick timer in Cortex-M systems:
- Generating periodic interrupts for a real-time OS scheduler – Set the reload value to the desired scheduler interval and enable interrupts.
- Measuring brief time intervals – Sample the CVR timer value at start and end of interval to determine elapsed cycles.
- Creating delay loops – Busy wait checking the COUNTFLAG bit in CSR until elapsed.
- Timeout detection – Set CVR to timeout value, poll COUNTFLAG bit to detect timeout.
- Simple profiling – Measure intervals between events by sampling CVR.
The SysTick timer is commonly used in RTOSes for Cortex-M like FreeRTOS to generate periodic ticks for scheduling. A 1ms tick is typical, achieved by loading the number of cycles in 1 millisecond into SYST_RVR. When using the SysTick for RTOS ticks, interrupts should be enabled to trigger the scheduler on each tick.
For measuring short time intervals, the CVR timer value can be sampled right before and after the interval to determine the elapsed cycles. This provides basic profiling or benchmarking capabilities.
Busy wait delay loops can suspend execution by polling the COUNTFLAG bit in CSR until the timer expires. This technique can be used for short delays without consuming CPU cycles unnecessarily.
To implement timeout detection, the CVR timer can be preloaded with the timeout value, then code can periodically check if COUNTFLAG is set to detect a timeout occurred.
SysTick Registers
The SysTick timer functionality is controlled through several registers in the System Control Block:
- SYST_CSR – SysTick Control and Status Register
- SYST_RVR – SysTick Reload Value Register
- SYST_CVR – SysTick Current Value Register
- SYST_CALIB – SysTick Calibration Value Register
The SYST_CSR register is used to enable the timer, enable interrupts, and monitor current status. Bits include:
- ENABLE – Set 1 to enable timer, clears on expiration
- TICKINT – Set 1 to enable SysTick exception on expiration
- COUNTFLAG – Set on expiration, cleared on read
SYST_RVR stores the reload value that gets loaded into the current value register when the timer reaches zero. This determines the period of the timer interrupts.
SYST_CVR holds the current timer value and decrements each clock cycle. Software can directly read/write this register to get or set the current value.
SYST_CALIB is a read-only register with the 10-bit calibration value used internally to determine 1 second intervals. Can be used to scale timing measurements.
SysTick Handler
If interrupts are enabled for the SysTick timer, the processor will trigger the SysTick exception handler on expiration. This handler needs to have specific naming syntax: void SysTick_Handler(void) { // Interrupt Service Routine }
The Cortex-M will automatically jump to this handler when the COUNTFLAG bit becomes set. The handler can then invoke RTOS scheduling logic or other timed tasks.
It is common to call OS tick handlers from the SysTick_Handler() routine. This allows the RTOS to perform foreground/background context switches and manage task states.
OS Integration
The SysTick timer is designed to integrate cleanly with a RTOS scheduler. For an OS like FreeRTOS, the SysTick is configured to generate interrupts at the required tick interval, say every 1ms. FreeRTOS provides the function vPortSetupTimerInterrupt() to initialize the SysTick registers for the proper tick rate.
On each tick interrupt, FreeRTOS kernel code executes to determine if the running task should be switched out. This allows precise task scheduling according to configured priorities and policies in the RTOS.
The OS Tick handler will service timer ticks by incrementing the OS tick counter, determining if any delayed tasks should execute, and scheduling the highest priority task. Task timing and delays are driven by the OS tick counter using the periodic SysTick interrupts.
Advantages of the SysTick Timer
Here are some benefits of using the SysTick timer in Cortex-M systems:
- Integrated into CPU – No need for external timer module
- Wide range of intervals – From 1 to 16M+ cycles
- Dedicated exception handler
- Low power capable – Can run in sleep modes
- Relatively small code footprint
- Supported by RTOSes like FreeRTOS
Since the SysTick timer is built into the core CPU, it eliminates the need for external counter/timer chips in many cases. The 24-bit range can cover a wide variety of intervals. Dedicated exception handling also makes it efficient for OS context switching.
Power consumption is low since no external logic is required. The timer can even operate in reduced power modes allowing wakeups from sleep states. Due to its simplicity, the SysTick has a much smaller code footprint than more advanced timer modules.
Finally, the timer receives direct support from small RTOS kernels designed for Cortex-M. It integrates seamlessly to provide the tick source for scheduling, delays, timeouts, and more.
Limitations of SysTick
While versatile, the SysTick timer has some limitations including:
- 24-bit countdown range limits intervals
- Only single interval – No capture/compare channels
- No external clocking option
- Limited programmability of interrupts
- No input capture or PWM generation capabilities
The 24-bit range, while wide, may be insufficient for some applications needing very long delays or short precision below 1 microsecond. Only a single interval is supported, with no compare channels for flexibly generating outputs.
External clocking is not available, so the timer always uses the core CPU clock. Interrupt flexibility is also limited compared to more advanced timers. The SysTick provides simple periodic timeouts but lacks features like input capture or hardware PWM generation.
For applications needing additional capabilities like multiple compare outputs, wider bitrates, or capture inputs, an additional timer/counter peripheral would be required in addition to the SysTick.
Conclusion
The SysTick timer in ARM Cortex-M processors fills an important role by enabling basic timekeeping abilities with minimal hardware. Its periodic interrupt capability allows clean integration with a small real-time OS for task scheduling and context switching. While limited compared to a dedicated timer/counter module, the SysTick’s simplicity and integration are well suited for resource constrained microcontrollers in embedded systems.