Main Content

Time-Based Scheduling and Code Generation

Sample Time and Blocks that Compute State

The sample time of a block in a Simulink® model specifies when the block produces output, and if appropriate, updates its internal state during simulation or generated code execution. The internal state of a block includes but is not limited to continuous and discrete states that Simulink computes and logs. For blocks that define discrete states Simulink computes the values of the states at each time step. Blocks that define continuous states rely on numerical integration for the computation of internal state values. A model can include continuous blocks, discrete blocks, or continuous and discrete blocks. Models that include both types of blocks are hybrid systems.

Typically, you use continuous blocks to model equations in integral form in variable steps so that you can control the accuracy of simulations. MathWorks® does not recommend using continuous blocks in models from which you intend to generate production code, especially for safety-critical applications. Continuous blocks rely on numerical integration to compute continuous state, which can impact determinism of software execution and numerical accuracy for the execution rate of the generated code. After achieving required results, you can convert continuous blocks to discrete blocks (see Discretization), which have a predictable number of steps because you know the fixed step size.

Embedded Coder® does not support the use of continuous blocks by default, or for models configured to use a service code interface.

If you are using Embedded Coder (for example, if System target file is set to ert.tlc) to generate code from a model that includes continuous blocks, select the model configuration parameter Support: continuous time (Embedded Coder).

For more information about using Continuous and Discrete blocks in models from which you intend to generate code, see these pages:

Multirate Systems and Rate Transitions

You can model single-rate and multirate discrete systems and hybrid continuous-discrete systems by setting block sample times that control the rate of block calculations and execution. Simulink provides considerable flexibility for designing multirate systems. For a multirate model to operate as expected in real time, the model must handle rate transitions between blocks configured to use different sample times.

By default, the Simulink engine returns errors during simulation if a model contains unprotected rate transitions. Use the diagnostic model configuration parameter Multitask data transfer to specify whether the Simulink engine displays a warning and returns an error after detecting an invalid transition.

To avoid rate transition errors, insert Rate Transition blocks between blocks configured to use different sample times. You can insert the Rate Transition blocks explicitly or you can configure a model so that the Simulink engine detects mismatched rate transitions during a diagram update and inserts hidden Rate Transition blocks for you. To instruct the Simulink engine to insert the blocks, select the model configuration parameter Automatically handle rate transition for data transfer.

To understand the importance of detecting and handling rate transitions, consider how Simulink simulations differ from real-time program execution.

Rate Transitions During Model Simulation

Before simulating a model, the Simulink engine orders the blocks in the model based upon their topological dependencies. This includes expanding virtual subsystems into the individual blocks they contain and flattening the model into a single list. Once this step is complete, each block executes in order.

The key to this process is the ordering of blocks. A block that produces output that is directly dependent on the block input (that is, a block with direct feedthrough) cannot execute until the block driving the input executes.

Rate Transitions During Real-Time Program Execution

A real-time program differs from a Simulink simulation in that the program must execute the model code synchronously with real time. Every calculation results in some computational delay. This means the sample intervals cannot be shortened or lengthened (as they can be in a Simulink simulation), which leads to less efficient execution. Rate transitions are relevant when multiple tasks might access the same data simultaneously.

Consider this timing diagram.

In the diagram, the vertical lines that are labeled t0, t1, and t2 indicate sample time hits. The blue areas represent execution by the Simulink engine. The blank spaces show time during which the processor is idle.

A processing inefficiency occurs in the sample interval from times t1 to t2. That interval cannot be compressed to increase execution speed because, by definition, sample times are clocked in real time.

You can circumvent the inefficiency by configuring code generation for a model in multitasking mode. Multitasking mode defines tasks with different priorities to execute parts of the model code that have different sample rates. See Tasking Modes.

Discretization

Discretization is the process of replacing continuous blocks with discrete equivalents. If a model includes continuous blocks and you are ready to generate production code or perform hardware-in-the-loop (HIL) simulations, consider these options for discretizing the model.

  • If you have a Control System Toolbox™ license, Version 5.2 or higher, use the Simulink Model Discretizer app to:

    • Identify continuous blocks in a model.

    • Change block parameters from continuous to discrete.

    • Apply discretization settings to continuous blocks.

    • Create variant subsystems that contain multiple discretization candidates and original continuous blocks.

    • Switch between discretization candidates and evaluate model simulation results.

    For an example, see Discretize a Model with the Model Discretizer.

  • If you have a Control System Toolbox or System Identification Toolbox™ license, use the c2d function to discretize a state and then place the discrete state in a model.

Tasking Modes

For models configured to use a fixed-step solver, the code generator supports two tasking modes (modes of execution) for periodic sample times: single-tasking and multitasking. See Configure Tasking Mode for information on how to switch between the two modes.

Single-Tasking Mode

Setting up a model in single-tasking mode can:

  • Simplify the model.

  • Negatively impact execution speed.

In single-tasking mode, the base sample rate for a model must define a time interval that is long enough to execute one step of the model (that is, all blocks in the model) within that interval.

This timing diagram shows the inefficiency inherent when using single-tasking mode.

In the diagram, the vertical lines that are labeled t0 to t4 indicate sample time hits. The blue areas represent execution by the Simulink engine. The blank spaces show time during which the processor is idle.

For more information about single-tasking execution and examples, see Tasking Modes and Execution Order.

Multitasking and Pseudomultitasking Modes

When periodic tasks execute in multitasking mode, by default the blocks with the fastest sample rates execute as the task with the highest priority, the next fastest blocks execute as the task with the next higher priority, and so on. Time available between the processing of high-priority tasks is used for processing lower priority tasks. This results in more efficient program execution.

When tasks are asynchronous rather than periodic, there might not be a relationship between sample rates and task priorities; the task with the highest priority need not have the fastest sample rate. You specify asynchronous task priority numbers by using Async Interrupt and Task Sync blocks. You can switch the sense of what priority numbers mean (that is, whether higher or lower priority number correspond to higher priority tasks) by selecting or clearing the model configuration parameter Higher priority value indicates higher task priority.

In multitasking environments that include a real-time operating system, you can define separate tasks and assign them priorities. For bare-metal target hardware where a real-time operating system is not present, you cannot create separate tasks. However, generated application modules implement what is effectively a multitasking execution scheme by using overlapping interrupts and programmatic context switching.

This means that an interrupt can occur while another interrupt is currently in progress. When this happens, the current interrupt is preempted, the floating-point unit (FPU) context is saved, and the higher priority interrupt executes its higher priority (that is, faster sample rate) code. Once complete, control returns to the preempted interrupt service routine (ISR).

In the next two timing diagrams:

  • Vertical solid lines that are labeled t0 to t4 indicate sample time hits.

  • Blue areas represent execution by the Simulink engine.

  • Blank spaces show time during which the processor is idle.

  • Hashed areas indicate task preemption by a higher priority task.

  • Vertical dotted lines with downward pointing arrows indicate the release of control of the CPU to a lower priority task.

  • Vertical dotted lines with upward pointing arrows indicate preemption by a higher priority task.

This diagram shows how timing of tasks in multirate systems are handled in a multitasking environment.

The next diagram shows how overlapped interrupts are used to implement pseudomultitasking. In this case, Interrupt 0 does not return until after Interrupts 1, 2, and 3 finish executing. The dark lines the execution paths of the interrupts

Note

A model that is multirate and uses multitasking cannot reference a multirate model that uses single-tasking.

For information about multitasking execution and examples, see Tasking Modes and Execution Order.

Tasking Considerations

  • Single-tasking programs require longer sample intervals because all computations must execute within each clock period. This can result in inefficient use of available CPU time.

  • If a model is large and has many blocks executing at different rates, multitasking mode can improve the efficiency of your program.

  • If a model is dominated by a single rate and only a few blocks execute at a slower rate, multitasking can degrade performance. The overhead incurred from task switching can be greater than the time required to execute the slower blocks. In this case, it is more efficient to execute all blocks at the dominant rate.

  • If a model can benefit from multitasking execution, add Rate Transition blocks (or instruct the Simulink engine to do so) to generate expected results.

Related Topics