NetBurner 3.5.7
PDF Version
Timers

Topics

 High Resolution Delay Timer
 High-precision microsecond delay functionality.
 
 Interval Timer
 
 Stopwatch Timer
 

Detailed Description

Hardware based high resolution timers:

Software tick-based task delay:

Timer API Hardware Reference

Overview

NetBurner provides three hardware timer APIs plus one software tick-based task delay:

API Header Purpose
HiResDelay (DelayObject) HiResDelay.h Blocking microsecond-precision delays
IntervalTimer IntervalTimer.h Periodic callbacks, semaphore posts, or flag sets
StopWatch stopwatch.h High-resolution elapsed time measurement
OSTimeDly() nbrtos.h Block the calling task for N RTOS system ticks (no hardware timer consumed)

Each hardware API allocates timers from the underlying CPU's hardware timer peripherals. The number of available timers and the specific hardware used varies by CPU family. This document maps each platform to its timer hardware and documents resource limits.

OSTimeDly() is a software delay built on the existing RTOS system tick — it does not consume any hardware timer from the pools described below. See the OSTimeDly (Software Task Delay) section near the end of this document.

Platform-to-CPU Mapping

Platform CPU Architecture Timer Hardware
MOD5441X MCF5441X ColdFire DMA Timers + PIT Timers
NANO54415 MCF5441X ColdFire DMA Timers + PIT Timers
SB800EX MCF5441X ColdFire DMA Timers + PIT Timers
MODM7AE70 SAME70 Cortex-M7 TC (Timer Counter) Channels
SBE70LC SAME70 Cortex-M7 TC Channels
SOMRT1061 MIMXRT10xx Cortex-M7 Quad Timers (QTimer)
MODRT1171 MIMXRT11xx Cortex-M7 Quad Timers (QTimer)

Timer Availability Summary

CPU Family HiResDelay Pool IntervalTimer Pool StopWatch Source Total HW Timers
MCF5441X 4 DMA timers (shared with StopWatch) 2 PIT timers (PIT 1-2) 1 DMA timer (shared from same 4) 4 DMA + 4 PIT
SAME70 12 TC channels (shared pool) 12 TC channels (shared pool) SysTick (no timer consumed) 12 TC
MIMXRT10xx 12 QTimer channels (shared pool) 12 QTimer channels (shared pool) System QTimer pair (no user timer consumed) 12 QTimer
MIMXRT11xx 12 QTimer channels (shared pool) 12 QTimer channels System QTimer pair (no user timer consumed) 12 QTimer

System-Reserved Timers

Each CPU reserves certain timer hardware for the RTOS system tick. These timers are not available to user code and are already excluded from the timer API allocation pools.

CPU Reserved Hardware Purpose Configured In
MCF5441X PIT 0 RTOS system tick (OSTickISR) platform/*/source/hal.cpp via sim2.pit[0]
PIT 3 Debugger platform/*/source/hal.cpp via sim2.pit[3]
SAME70 ARM SysTick RTOS system tick (SysTick_Handler) platform/*/source/hal.cpp via SysTick_Config()
MIMXRT10xx/11xx TMR4 channels 2-3 RTOS system tick (SysTick_Handler) platform/*/source/hal.cpp via SysTmrLo/SysTmrHi on TMR4

Key points:


MCF5441X (ColdFire)

Platforms: MOD5441X, NANO54415, SB800EX

DMA Timers (HiResDelay + StopWatch)

The MCF5441X has 4 DMA timers (DMA Timer 0-3), accessed through sim2.timer[0..3]. These are 32-bit free-running timers clocked at CPU_CLOCK / 2 (~75 MHz at 150 MHz CPU clock).

Timer allocation: FIRST_UNUSED_TIMER scans sim2.timer[0..3], selecting the first timer whose TMR register bit 0 is clear (timer disabled).

Clock and resolution:

Short-delay busy-wait: Delays <= 20 us use a hand-tuned busy-wait loop instead of the hardware timer to avoid semaphore overhead. The loop uses nop instructions calibrated for the ColdFire pipeline.

Max single delay: The 32-bit reference register allows delays up to 0xFFFFFFFF / (CPU_CLOCK/2) seconds (~57 seconds at 75 MHz).

Source files:

PIT Timers (IntervalTimer)

The MCF5441X has 4 PIT (Programmable Interrupt Timer) modules. PIT 0 is reserved for the RTOS system tick, and PIT 3 is reserved for the debugger. PIT 1 and PIT 2 are available for application IntervalTimer use.

Prescaler: The prescaler is auto-selected to fit the desired frequency within the 16-bit counter range. Divider values range from 2 to 32768 (4-bit field, powers of 2).

Minimum frequency: The code checks num_per_sec < 1 (returns -2), so the practical minimum is 1 Hz. The header documentation recommends >= 20 Hz.

Source files:


SAME70 (Cortex-M7)

Platforms: MODM7AE70, SBE70LC

TC (Timer Counter) Channels (HiResDelay + IntervalTimer)

The SAME70 has 4 TC blocks (TC0-TC3), each with 3 channels, totaling 12 TC channels (timers 0-11). These are managed by a unified dispatch system (timer_dispatch.cpp) with a 16-bit timerInUse bitmask.

Timer dispatch architecture (timer_dispatch.cpp):

Clock selection (IntervalTimer): The driver auto-selects the clock source that minimizes frequency error:

Each option is evaluated with ClockCheck() and the best-fit is chosen. The 16-bit compare register limits the maximum divider per clock source to 65535.

Clock (HiResDelay): Uses TC_CMR_TCCLKS_TIMER_CLOCK2 (PERIPH_CLOCK / 8). At 300 MHz CPU, PERIPH_CLOCK is typically 150 MHz, giving 18.75 MHz timer clock (75/4 ticks per microsecond).

Short-delay busy-wait: Delays <= 20 us use a calibrated busy-wait loop (magic number 55).

Max single HiResDelay: ~3400 us per hardware delay cycle (16-bit compare register at 18.75 MHz). Longer delays are handled by chaining multiple 3001 us delays.

StopWatch

StopWatch on SAME70 uses the ARM SysTick timer, which is already running for the RTOS tick. No additional hardware timer is consumed.

Resolution: 1 / CPU_CLOCK seconds per tick (~3.3 ns at 300 MHz).

Source files:


MIMXRT10xx (Cortex-M7)

Platforms: SOMRT1061

Quad Timers (HiResDelay + IntervalTimer)

The MIMXRT10xx has 3 QTimer modules (TMR1[0..2]), each with 4 channels, totaling 12 QTimer channels (timers 0-11). HiResDelay and IntervalTimer share this pool.

Timer allocation** (FindUnusedTimer()): Iterates modules 0-2, channels 0-3 (12 total). A channel is free if intervalCtx[].type == None AND COMP1 == 0 AND COMP2 == 0.

Prescaling (IntervalTimer): 8 hardware prescale levels (QTMR_PRI_CLK_DIV_1 through QTMR_PRI_CLK_DIV_128, shifting PERIPH_CLOCK by 0-7 bits). If prescale 7 is still insufficient for the desired frequency, a software divider (swDiv = 0xF, dividing by 16) extends the range further. The 16-bit compare register limits the count per prescale level to 65535.

Clock (HiResDelay): Uses QTMR_PRI_CLK_DIV_1 (no prescale), counting at PERIPH_CLOCK (typically 132 MHz on SOMRT1061). This gives ~132 counts per microsecond.

Short-delay busy-wait: Delays <= 21 us use a calibrated busy-wait loop (magic number 63 for inner loop, 58 for startup).

Max single HiResDelay: ~498 us per hardware delay cycle (0xFFFF / (PERIPH_CLOCK / 1000000)). Longer delays are handled by chaining multiple 497 us delays.

StopWatch

StopWatch on MIMXRT10xx uses a pre-allocated linked QTimer pair (SysTmrLo / SysTmrHi) that is already set up by the HAL for system timekeeping. No user QTimer channel is consumed.

Resolution: 1 / (PERIPH_CLOCK / 16) seconds per tick. At 132 MHz PERIPH_CLOCK, this is 1 / 8,250,000 = ~121 ns.

Source files:


MIMXRT11xx (Cortex-M7)

Platforms: MODRT1171

Quad Timers (IntervalTimer only)

The MIMXRT11xx has the same 3 QTimer modules x 4 channels = 12 QTimer channels as MIMXRT10xx. The IntervalTimer implementation is structurally identical to MIMXRT10xx.

Key difference from MIMXRT10xx: The MIMXRT11xx IntervalTimer.cpp does not include the DelayObject (HiResDelay) implementation. There is no separate HiResDelay.cpp for this CPU. HiResDelay is not available on MIMXRT11xx platforms.

StopWatch

Identical to MIMXRT10xx. Uses the pre-allocated SysTmrLo / SysTmrHi QTimer pair. No user timer consumed.

Resolution: 1 / (PERIPH_CLOCK / 16) seconds per tick, same as MIMXRT10xx.

Source files:


Timer Allocation Details

FIRST_UNUSED_TIMER

All three APIs accept FIRST_UNUSED_TIMER (defined as -1 in constants.h) as the default timer parameter. This triggers automatic allocation of the next available hardware timer.

Error Codes

Return Value Meaning
>= 0 Success: allocated timer number
-1 No hardware timer available (all in use)
-2 Invalid frequency (IntervalTimer: < 1 Hz in code, recommended >= 20 Hz)

Resource Management

Practical Timer Budgets

CPU Max Concurrent DelayObjects Max Concurrent IntervalTimers StopWatch Cost
MCF5441X 3 (if StopWatch uses 1 DMA timer) 2 (PIT 1-2) 1 DMA timer (shared)
SAME70 12 minus active IntervalTimers 12 minus active DelayObjects Free (SysTick)
MIMXRT10xx 12 minus active IntervalTimers 12 minus active DelayObjects Free (system QTimer)
MIMXRT11xx N/A (not available) 12 Free (system QTimer)

Implementation Reference

Source File Paths

CPU HiResDelay IntervalTimer StopWatch Timer Dispatch
MCF5441X arch/coldfire/cpu/MCF5441X/source/HiResDelay.cpp arch/coldfire/cpu/MCF5441X/source/IntervalTimer.cpp + pitr_sem.cpp arch/coldfire/cpu/MCF5441X/source/stopwatch.cpp N/A (direct register access)
SAME70 arch/cortex-m7/cpu/SAME70/source/HiResDelay.cpp arch/cortex-m7/cpu/SAME70/source/IntervalTimer.cpp arch/cortex-m7/cpu/SAME70/source/stopwatch.cpp arch/cortex-m7/cpu/SAME70/source/timer_dispatch.cpp
MIMXRT10xx Combined in IntervalTimer.cpp arch/cortex-m7/cpu/MIMXRT10xx/source/IntervalTimer.cpp arch/cortex-m7/cpu/MIMXRT10xx/source/stopwatch.cpp N/A (inline in IntervalTimer.cpp)
MIMXRT11xx Not available arch/cortex-m7/cpu/MIMXRT11xx/source/IntervalTimer.cpp arch/cortex-m7/cpu/MIMXRT11xx/source/stopwatch.cpp N/A (inline in IntervalTimer.cpp)

Headers

Clock Formulas

CPU StopWatch Resolution StopWatch Convert
MCF5441X 2.0 / CPU_CLOCK sec/tick ticks * 2.0 / CPU_CLOCK seconds
SAME70 1.0 / CPU_CLOCK sec/tick ticks / CPU_CLOCK seconds
MIMXRT10xx/11xx 1.0 / (PERIPH_CLOCK / 16) sec/tick ticks / (PERIPH_CLOCK / 16) seconds

Typical Clock Values

CPU Clock Variable Typical Value StopWatch Tick
MCF5441X CPU_CLOCK 150 MHz ~13.3 ns
SAME70 CPU_CLOCK 300 MHz ~3.3 ns
MIMXRT10xx PERIPH_CLOCK 132 MHz ~121 ns
MIMXRT11xx PERIPH_CLOCK 240 MHz ~66.7 ns

OSTimeDly (Software Task Delay)

OSTimeDly() is the RTOS primitive for delaying the currently executing task by a number of system ticks. Unlike the three hardware timer APIs above, it is built on the existing RTOS system tick and does not allocate a hardware timer from any pool.

Declaration:

void OSTimeDly(uint32_t to_count);
void OSTimeDly(uint32_t to_count)
Delay the task until the specified value of the system timer ticks. The number of system ticks per se...
Definition nbrtos.h:1846

Tick Duration

The number of system ticks per second is defined by TICKS_PER_SECOND in nbrtos/include/constants.h. The default is 20 ticks/second (50 ms per tick). Always express delays in terms of TICKS_PER_SECOND rather than a hard-coded count so the code remains correct if the tick rate is changed:

OSTimeDly(TICKS_PER_SECOND); // Delay 1 second
OSTimeDly(TICKS_PER_SECOND * 2); // Delay 2 seconds
OSTimeDly(TICKS_PER_SECOND / 10); // Delay 100 ms
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49

When to Use OSTimeDly vs. HiResDelay

Characteristic OSTimeDly() DelayObject (HiResDelay)
Resolution 1 system tick (50 ms default) Microseconds
Hardware cost None 1 hardware timer per object
Behavior Task-level reschedule; other tasks run during delay Blocks on semaphore/busy-wait; short delays busy-wait
Typical use Polling loops, periodic task work, pacing network retries Precise pulse widths, microsecond-accurate bus timing
Callable from ISR No No (constructor must not run in ISR)

Use OSTimeDly() for any delay coarser than a few tick periods where microsecond accuracy is not required. It costs no hardware timer resources and is the idiomatic way to pace task loops in NetBurner applications.

Related Functions

Function Purpose
OSTimeDly(ticks) Delay for ticks system ticks relative to now
OSTimeWaitUntil(tickValue) Delay until TimeTick reaches an absolute value
OSChangeTaskDly(prio, ticks) Change an already-delayed task's wake-up to ticks from now

See also: OSTimeWaitUntil(), OSChangeTaskDly(), TimeTick, TICKS_PER_SECOND.

Source: nbrtos/include/nbrtos.h