RT Time and Intervals

Handling of time is a fundamental mechanism in ChibiOS/RT, it is quite important to understand some basic concepts:

  • System Tick.
  • System Time.
  • Time Intervals.
  • Time units.
  • Tick-less mode.
  • High Resolution mode.

Global Settings

CH_CFG_ST_RESOLUTION System time type systime_t resolution in bits, the value can be 16 or 32.
CH_CFG_ST_FREQUENCY System time frequency. Defines the working frequency of the system time increase.
CH_CFG_ST_TIMEDELTA If zero then the kernel uses the classic tick mode, in alternative the tickless mode is activated. Values greater or equal to two defines the minimum number of ticks for intervals, the value one is forbidden.
CH_CFG_INTERVALS_SIZE Size in bits of the sysinterval_t type, the value can be 16, 32 or 64.
CH_CFG_TIME_TYPES_SIZE Size of the time types time_secs_t, time_msecs_t and time_usecs_t, the value can be 16 or 32. Note that an additional time time_conv_t is also defined which has double size in bits, this type is used internally for safe time conversions.

Definitions

Definitions of terms used:

System Tick

The system tick is the atomic unit of time in ChibiOS/RT, time is measured in ticks. The system tick increases the system time counter.

System Time

System time is a counter of type systime_t increased by the System Tick, when the counter reaches its maximum value then it returns to zero, this does not affect functionality, the counter is meant to be able to wrap. The type systime_t is used for absolute time, specific instants in the system time domain.

Time Intervals

A time interval is a time period measured in system ticks. Note that intervals have their own time sysinterval_t not to be confused with systime_t which is used for absolute time. Note that the sysinterval_t type can be larger than systime_t, this means that intervals can be larger than the system time counter range capability. Time intervals and system times must never be mixed, there are conversion functions to be used for time calculations.

Time Units

A time units are used to define intervals using standard time units rather than system ticks. Time units have their own types: time_secs_t, time_msecs_t and time_usecs_t. Utilities are provided for converting from time units to time intervals and vice versa. Note that time units cannot be used for absolute time (systime_t), only time intervals can be converted to/from time units.

Time Period

It is a couple of systime_t representing the “start time” and the “end time” of an absolute time period.

System Time Counter

The system time is kept by a global counter of type systime_t which is incremented by the system tick. For example, if the system tick has 1mS period then the system time is incremented with a 1mS rate.

Note that in RT there are 2 distinct strategies for handing the system time:

Classic Mode

The system time is a regular variable which is incremented by a periodic interrupt running at the system tick rate. This is what most RTOSes do.

The advantages are:

  • The implementation is simple and this mode is always available.

Drawbacks:

  • The CPU has to serve continuous interrupts in order to increase the counter.
  • High resolution system time is not possible, interrupts would saturate the CPU.
  • The counter increase is subject to interrupts jitter.
  • The system time is not increased during critical sections.

Tick-less Mode

The system time is an HW counter within some system timer, no interrupts are required in order to increase the counter.

The advantages are:

  • No periodic interrupts.
  • Able to count even at very high system tick rates without saturating the CPU with continuous interrupts.
  • No jitter, system time is not affected by critical sections and other interrupts, it is an HW counter.
  • The system time is increased even during critical sections.

Drawbacks:

  • Requires a specific HW support (specifically a dedicated timer with a prescaler, a counter and a comparator register).
  • SW handling of virtual timers is more complex so there is a moderate increase in code size, see the Virtual Timers chapter.

Time and Interval Example

In the picture we have:

  • The system time as the dotted line, note, it wraps at some point.
  • An interval (B - A) in system ticks.
  • The same interval (B - A) in milliseconds (it is rounded to the next mS boundary).
  • The absolute time is also shown in milliseconds but it cannot be obtained by system time, just a reference.

System Time Access API

Functions for accessing the system time. Note that the system time mode, classic or tick-less, is hidden by the API, from the application perspective it is the same.

chVTGetSystemTime() Returns the current system time.
chVTGetSystemTimeX() Returns the current system time (X-Class variant). This function can be called from any context but its atomicity is not guaranteed on architectures whose word size is less than systime_t size.
chVTTimeElapsedSinceX() Returns the interval since the specified system time.
chVTIsSystemTimeWithin() Returns true if the current system time is within the specified time period.
chVTIsSystemTimeWithinX() Returns true if the current system time is within the specified time period (X-Class variant).

Time Utilities API

Functions to convert and make calculations using time and intervals.

chTimeAddX() Adds an interval to a system time and returns a new system time.
chTimeDiffX() Returns the interval between two system times.
chTimeIsInRangeX() Returns true if the specified system time is within the specified time period.
chTimeS2I() Converts an interval from seconds to ticks, safe form.
chTimeMS2I() Converts an interval from milliseconds to ticks, safe form.
chTimeUS2I() Converts an interval from microseconds to ticks, safe form.
chTimeI2S() Converts an interval from ticks to seconds, safe form.
chTimeI2MS() Converts an interval from ticks to milliseconds, safe form.
chTimeI2US() Converts an interval from ticks to microseconds, safe form.
TIME_S2I() Converts an interval from seconds to ticks, faster unsafe form.
TIME_MS2I() Converts an interval from milliseconds to ticks, faster unsafe form.
TIME_US2I() Converts an interval from microseconds to ticks, faster unsafe form.
TIME_I2S() Converts an interval from ticks to seconds, faster unsafe form.
TIME_I2MS() Converts an interval from ticks to milliseconds, faster unsafe form.
TIME_I2US() Converts an interval from ticks to microseconds, faster unsafe form.

Note that all conversion functions/macros approximate in excess so converting 0.1mS (in ticks) using chTimeI2MS() would return 1.

Examples

Reading System Time

  /* Getting the number of ticks since the "epoch": the instant of
     the system initialization.*/
  systime_t now = chVTGetSystemTime();

Time Bounded Loop

A loop executes performs an internal activity until a condition is met or a specified time period expires.

  /* The following loop executes for 200 milliseconds or until an internal
     condition is met, whichever comes first.*/
  systime_t start = chVTGetSystemTime();
  systime_t end = chTimeAddX(start, TIME_MS2ST(200));
  while (chVTIsSystemTimeWithin(start, end) {
 
    ...;
 
    if (condition)
      break;
 
    ...;
  }

Timeout in Milliseconds

Many functions can have a timeout specification as a time interval, it is also possible to specify timeouts using normal time units.

  /* Waiting for a network event with a timeout of 200 milliseconds.*/
  chSysLock();
  msg_t msg = chThdEnqueueTimeoutS(&rx_frames_queue,
                                   TIME_MS2ST(200));
  if (msg == MSG_TIMEOUT) {
    /* Timeout management.*/
    ...;
  }
  chSysUnlock();