Main Content

Timer Representation and Computation

A timer measures and tracks time intervals. Time intervals are durations of time between two events, actions, or points in time. Time intervals are measured in units, such as seconds. For example, you might use time intervals in software to:

  • Schedule and coordinate tasks to execute at specific times or after specific durations.

  • Measure the duration of or intervals between occurrences of tasks, processes, events.

  • Complete computations that involve time, such as the duration of an activity or rates or frequencies based on time.

  • Synchronize processes in distributed systems or networks.

Timers provide a way to trigger actions or events based on specific time intervals or at predetermined points in time. You use timers in applications and systems to control processes, synchronize events, and trigger actions at regular intervals. Examples of types of timers include:

  • Hardware timers

  • Software timers

  • Real-time clocks (RTC)

  • Watchdog timers (WDT)

Timer interrupts trigger actions or events at periodic time intervals. When a timer interrupt occurs, the system interrupts its execution to run a routine associated with the interrupt. You might use a timer interrupt to update displays, sample sensor data, or execute periodic tasks.

Time Intervals and Simulink Models

Some Simulink® blocks and Stateflow® charts depend on time values to compute output. When you include such blocks or charts in a model, the code generator implicitly produces the required code for representing absolute time or elapsed time depending on the block or chart requirement. Absolute time is the time interval from the start of program execution to the time when the function that includes code for a block that uses absolute time starts executing. Elapsed time is the time interval between two consecutive executions of a block. The Digital Clock block is an example of a block that depends on absolute time. Stateflow charts that depend on time use absolute time. If you log time values by selecting model configuration parameter Time, the model uses absolute time. The Discrete-Time Integrator block is an example of a block that depends on elapsed time.

For a list of Simulink blocks that depend on absolute time, see Blocks That Depend on Absolute Time. Some blocks in other blocksets depend on absolute time. See the documentation for the blocksets that you use.

For models that include blocks or charts that depend on time and are configured to use an ERT-based system target file for code generation, you must select model configuration parameter Support: absolute time. That parameter setting instructs the code generator to check for such blocks and, if at least one exists, to produce the relevant timer code. If the parameter is cleared and the model includes at least one such block or chart, the code generator returns an error.

Generated Timer Code

The code generator places timer code for blocks and Stateflow charts in the entry-point function generated from the part of the model that contains the blocks and charts. The timer code allocates memory for time counters and computes the time counter values. The timer code executes within scheduled periodic and aperiodic tasks. The code generator minimizes memory allocated for timers and reduces overhead associated with timer maintenance by producing only the timer code needed based on the modeling style and presence of blocks that depend on time.

Code Generated Based on Model Style and Rates

Model Styles and RatesCode Generated
Single-rate, rate-based model that includes at least one block that depends on timeCode for one timer
Multirate, rate-based modelCode for one timer per rate for which there are blocks that depend on time
Export function model (Embedded Coder®)Code for one timer per function that includes blocks that depend on time

Consider this multirate model.

A multirate model showing use of a Digital Clock block, a Gain block, and a triggered subsystem that includes a Discrete Time Integrator block, each of which executes at a different rate.

The Digital Clock, Gain, and Triggered Subsystem blocks run at sample rates 0.1, 0.2, and 0.3 seconds, respectively. The Digital Clock block depends on absolute time. The Triggered Subsystem block includes Discrete Time Integrator and Digital Clock blocks, which depend on elapsed and absolute time, respectively. The Gain block does not depend on time. For this model, the code generator produces code for two timers: one for sample rate 0.1 second and one for sample rate 0.3 second. The timing engine updates the time counters as the tasks associated with sample rates 0.1 second and 0.3 second run. Blocks running at those sample rates get the time data from the time counters for the corresponding sample rates.

Assuming that model configuration parameter Application lifespan (days) is set to 1 and MAT-file logging is cleared, the code generator produces this timer code for the example model.

void timerBasics_step0(void)                 /* Sample time: [0.1s, 0.0s] */
{
  timerBasics_Y.Out2 = ((timerBasics_M->Timing.clockTick0) * 0.1);

  timerBasics_M->Timing.clockTick0++;
}
.
.
.
void timerBasics_step2(void)                 /* Sample time: [0.3s, 0.0s] */
{
  uint32_T TriggerSubsystem_ELAPS_T;
.
.
.
  if (zcEvent != NO_ZCEVENT) {
    if (timerBasics_DW.TriggerSubsystem_RESET_ELAPS_T) {
      timerBasics_DW.TriggerSubsystem_ELAPS_T  = 0U;
    } else {
      timerBasics_DW.TriggerSubsystem_ELAPS_T = timerBasics_M->Timing.clockTick2 -
        timerBasics_DW.TriggerSubsystem_PREV_T;
    }

    timerBasics_DW.TriggerSubsystem_PREV_T = timerBasics_M->Timing.clockTick2;
    timerBasics_DW.TriggerSubsystem_RESET_ELAPS_T = false;

    if (timerBasics_DW.DTI2_SYSTEM_ENABLE == 0) {
      timerBasics_DW.DTI2_DSTATE += 0.3 * (real_T)timerBasics_DW.TriggerSubsystem_ELAPS_T 
        * timerBasics_DW.DTI2_PREV_U;
    }

    timerBasics_B.DigitalClock2 = ((timerBasics_M->Timing.clockTick2) * 0.3);

  }

  timerBasics_Y.Out4 = timerBasics_B.DigitalClock2;

  timerBasics_M->Timing.clockTick2++;
.
.
.
}

The code for entry-point function timerBasics_step0 includes code for the Digital Clock block and runs at sample rate 0.1 seconds. It also:

  • Allocates memory to store the computed absolute time value.

  • Computes the absolute time by multiplying the clock tick (clockTick0) by the sample rate.

  • Returns the time at the specified sampling interval.

  • Uses clockTick0 to count the number of times the code for the task runs. The resolution of the timer is 0.1, the step size of the task.

The code generator does not produce code for entry-point function timerBasics_step1. The Gain block does not depend on time.

The code for entry-point function timerBasics_step2 includes code for the triggered subsystem that includes the Discrete-Time Integrator block and runs at sample rate 0.3 second:

  • Checks whether there is a need to reset the elapsed time. If a reset is needed, the elapsed time is set to 0. Otherwise, the function gets the current clock tick value to use to compute the current elapsed time and caches the previous clock tick value.

  • Computes the absolute time by multiplying the clock tick (clockTick2) by the sample rate (0.3 second).

  • Uses clockTick2 to count the number of times the code for the task runs.

If you create or maintain an S-Function block that requires absolute or elapsed time, the block must register the timer requirement as explained in Access Timers Programmatically.

For information on timer support for blocks that execute asynchronously with respect to the periodic timing source of a model, see Timers in Asynchronous Tasks and Create a Customized Asynchronous Library.

Timer Data Types and Memory Allocation

Simulink represents timers for absolute and elapsed time as unsigned integers. In generated code, the word size is set automatically to the minimum size that can accommodate the largest number of clock ticks that the algorithm uses. The code generator computes the largest number of clock ticks by dividing the product of the model application lifespan and 86,400, the number of seconds in one day, by the clock resolution.

Largest number of ticks = ((Application lifespan x 86400)/Clock resolution)

Application lifespan is the number of days an application that contains blocks or Stateflow charts depending on elapsed or absolute time run before a timer overflow occurs. You can adjust the application lifespan by using model configuration parameter Application lifespan (days). For models configured to use an ERT-based system target file and a data code interface, the application lifespan is set to 1 by default. For models configured to use a GRT-based system target file or an ERT-based system target file and service code interface, the default application lifespan is inf. When Application lifespan (days) is set to inf, the code generator can set the time counter to have a word size of up to 64 bits. The inf setting is for applications that run continuously. When you design an application that you intend to run continuously, you must take care when logging time values, or using blocks or charts that depend on absolute time. If the time counter reaches the largest value that can be represented by the data type of the timer, the timer overflows and the logged time or block output is incorrect.

Clock resolution is the smallest increment of a clock value in seconds. For example, if a clock increments its value once per second, the clock resolution is 1 second. Specify the clock resolution of a model by model configuration parameter Clock resolution (seconds, -1 inherited). By default, the parameter is set to -1 (inherit), which instructs the code generator to initialize the clock resolution based on scheduling properties for the model style and the type of an entry-point function. For example, the code generator sets the clock resolution for an aperiodic function in an export-function model to the model fixed-step size (fundamental sample time). For periodic functions, the clock resolution is set to the function sample time. If the model configuration parameter Type (SolverType) is set to Fixed-step and System target file (SystemTargetFile) is set to ert.tlc, you can use the Clock resolution (seconds, -1 inherited) parameter to set the clock resolution to a scalar value that represents the resolution in seconds.

For instance, if Application lifespan (days) is set to 1 and the clock resolution is 4 seconds, the largest number of clock ticks required is (1 x 86,400)/4 = 21,600 . To accommodate up to 21,600 ticks, the model requires a timer twith a word size that can accommodate at least 14 bits. In this case, the code generator declares the timer to use data type uint16_t, which handles a range of maximum number of ticks from 255 to 65,535.

The size of a time counter in generated code can be 8, 16, 32, or 64 bits. For each size, this table lists:

  • Range of the maximum number of clock ticks

  • Number of bits required

  • Simulink output data type specification

  • Data type that appears in generated code

  • Code interface support for the size

  • Examples

dfadf

Range of Maximum Number of Clock TicksNumber of BitsSimulink Output Data TypeData Type in Generated CodeExamples
[0, 255]8uint8uint8_t

  • Application lifespan: 0.01

  • Clock resolution: 4

Largest number of clock ticks: 216, 27 < 216 < 28

[255, 65535]16uint16uint16_t

  • Application lifespan: 1

  • Clock resolution: 4

Largest number of clock ticks: 21600, 214 < 21600 < 215

[65536, 4294967295]32uint32uint32_t

  • Application lifespan: 10

  • Clock resolution: 4

Largest number of clock ticks: 216000, 217 < 216000 < 218

[4294967296, inf]64
  • Data code interface: 2 uint32 words

  • Service code interface: uint64

  • Data code interface: 2 uint32_t words

  • Service code interface: uint64_t

  • Application lifespan: 1000000

  • Clock resolution: 4

Largest number of clock ticks: 21600000000, 234 < 21600000000 < 235

When Application lifespan (days) is set to inf, how Simulink represents time counters depends on the model code interface configuration. For a data code interface, Simulink represents time counters as two words of type uint32. For a service code interface, Simulink uses type uint64 to represent time counters.

For more information about controlling the data type word size that the code generator uses for time counters, see Optimize Memory Usage and Prevent Overflows for Time Counters.

The primary benefit of specifying a clock resolution is for the clock resolution to align with target environment clock requirements. For models configured to use a service code interface, specifying a clock resolution results in code that uses time values that produce more accurate results. As indicated above, a clock resolution influences the data type that Simulink and the code generator use to represent time values. For example, in normal, accelerator, and rapid accelerator modes, Simulink uses the specified clock resolution to deduce fixed-point data types, which produces fixed-point simulation and generated code execution output that match. For more information about specifying a clock resolution, see Specify Clock Resolution Used by Target Environment Clock.

The word size that the code generator applies for a time counter data type determines:

  • Type of DWork vector in a subsystem that maintains elapsed time.

  • Data type of output for the Weighted Sample Time block when the Output data type block parameter is set to Inherited: Inherit via internal rule.

Elapsed Time Counters in Triggered Subsystems

S-Function blocks that depend on elapsed time must register that requirement programmatically (see Access Timers Programmatically). A triggered subsystem then allocates and maintains one elapsed time counter if the triggered subsystem (or a unconditionally executed subsystem within the triggered subsystem) contains at least one block that depends on elapsed time. The time counter functions at the subsystem level, not at the individual block level, minimizing memory usage and overhead.

Note

If you are using simplified initialization mode, elapsed time is reset on the first execution after becoming enabled, whether or not the subsystem is configured to reset on enable. For more information, see Underspecified initialization detection.

Related Topics