Skip to content

Cycle Counter

lbuild module: modm:driver:cycle_counter

Allows you to measure time with cycle accuracy on AVR and ARM devices. This module wraps common functionality around different timers:

  • AVR: uses 16-bit TC1.
  • ARMv6-M (Cortex-M0/M0+): uses the 24-bit SysTick with limitations.
  • ARMv7-M (Cortex-M3 and above): uses the 32-bit DWT->CYCCNT.
// place counter in the fastest memory to limit sampling overhead
modm_fastdata modm::CycleCounter counter;
// initialize once before sampling
counter.initialize();

// Sample the timer now
counter.start();
// perform your operation and then sample again
counter.stop();

// you can now get cycles or milli-/micro-/nanoseconds
counter.cycles();
counter.nanoseconds();
counter.microseconds();
counter.milliseconds();

AVR TC1 Limitations

The 16-bit timer limits the maximum measurable time to just 4ms at 16MHz!

Cortex-M0 SysTick Limitations

The ARMv6-M architecture does not come with a free running counter, therefore this class uses the SysTick timer. However, the timer is already used by the modm:platform:systick module to provide modm::Clock, which limits the maximum measurable time to just 1ms! The systick may also be run with a /8 prescaler, which this class compensates for but this still reduces sampling resolution to 8 cycles!

In case these limitations are not acceptable, you may force initialize the SysTick, which will break modm::Clock functionality in favor of accurate measurements. You may of course reinitialize the SysTick after your measurement to regain modm::Clock functionality! However, the software timers of the modm:processing:timer module may not work correctly anymore and may need to be reinitialized.

// Always initializes the SysTick for `modm::Clock`
Board::initialize();

// but we need an accurate cycle counter
counter.initialize(/*force=*/true);
// do longer and more accurate measurement now
counter.start();
// do measurement operation
counter.stop();

// reinitialize the SysTick timer for `modm::Clock`
modm::platform::SysTick::initialize<Board::SystemClock>();

If this solution is not acceptable either, we recommend using a platform specific hardware timer instead.

This module is only available for avr, rp, sam, stm32.

Dependencies

modm:driver:cycle_counter modm_driver_cycle_counter modm: driver: cycle_counter modm_platform_core modm: platform: core modm_driver_cycle_counter->modm_platform_core modm_platform_cortex_m modm: platform: cortex-m modm_driver_cycle_counter->modm_platform_cortex_m

Limited availability: Check with 'lbuild discover' if this module is available for your target!