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 Rates | Code Generated |
---|---|
Single-rate, rate-based model that includes at least one block that depends on time | Code for one timer |
Multirate, rate-based model | Code 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.
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 Ticks | Number of Bits | Simulink Output Data Type | Data Type in Generated Code | Examples |
---|---|---|---|---|
[0, 255] | 8 | uint8 | uint8_t |
Largest number of clock ticks: 216, 27 < 216 < 28 |
[255, 65535] | 16 | uint16 | uint16_t |
Largest number of clock ticks: 21600, 214 < 21600 < 215 |
[65536, 4294967295] | 32 | uint32 | uint32_t |
Largest number of clock ticks: 216000, 217 < 216000 < 218 |
[4294967296, inf] | 64 |
|
|
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 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 an 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.