Main Content

Time-Based Scheduling and Code Generation

Sample Time Considerations

Simulink® models run at one or more sample times. The Simulink product provides considerable flexibility in building multirate systems, that is, systems with more than one sample time. However, this same flexibility also allows you to construct models for which the code generator cannot generate real-time code for execution in a multitasking environment. To make multirate models operate as expected in real time (that is, to give the right answers), you sometimes must modify your model or instruct the Simulink engine to modify the model for you. In general, the modifications involve placing Rate Transition blocks between blocks that have unequal sample times. The following sections discuss issues you must address to use a multirate model in a multitasking environment. For a comprehensive discussion of sample times, including rate transitions, see What Is Sample Time?, Sample Times in Subsystems, Sample Times in Systems and Subsystems, Resolve Rate Transitions, and associated topics.

Tasking Modes

There are two execution modes for a fixed-step model: single-tasking and multitasking. These modes are available only for fixed-step solvers. To select an execution mode, select model configuration parameter Treat each discrete rate as a separate task. When you select this parameter, multitasking execution is applied for a multirate model. When you clear this parameter, single-tasking execution is applied.

Note

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

Execution of models in a real-time system can be done with the aid of a real-time operating system, or it can be done on bare-metal target hardware, where the model runs in the context of an interrupt service routine (ISR).

The fact that a system (such as The Open Group UNIX® or Microsoft® Windows® systems) is multitasking does not imply that your program can execute in real time. This is because the program might not preempt other processes when required.

In operating systems (such as PC-DOS) where only one process can exist at a given time, an interrupt service routine (ISR) must perform the steps of saving the processor context, executing the model code, collecting data, and restoring the processor context.

Other operating systems, such as POSIX-compliant ones, provide automatic context switching and task scheduling. This simplifies the operations performed by the ISR. In this case, the ISR simply enables the model execution task, which is normally blocked. The next figure illustrates this difference.

Comparison of program execution using an interrupt service routine (bare metal with no operating system) and program execution using a real-time operating system primitive

Model Execution and Rate Transitions

To generate code that executes as expected in real time, you (or the Simulink engine) might need to identify and handle sample rate transitions within the model. In multitasking mode, by default the Simulink engine flags errors during simulation if the model contains invalid rate transitions. You can use the model configuration parameter Multitask data transfer to alter this behavior. Parameter Single task data transfer is available for the same purpose for single-tasking mode.

To avoid raising rate transition errors, insert Rate Transition blocks between tasks. You can request that the Simulink engine handle rate transitions automatically by inserting hidden Rate Transition blocks. See Automatic Rate Transition for an explanation of this option.

To understand such problems, first consider how Simulink simulations differ from real-time programs.

Execution During Simulink Model Simulation

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

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

Some blocks set their outputs based on values acquired in a previous time step or from initial conditions specified as a block parameter. The output of such a block is determined by a value stored in memory, which can be updated independently of its input. During simulation, computations are performed prior to advancing the variable corresponding to time. This results in computations occurring instantaneously (that is, no computational delay).

Model Execution in Real Time

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.

Consider the following timing figure.

Timing diagram that shows processing inefficiency in a sample interval

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

You can circumvent this potential inefficiency by using the multitasking mode. The multitasking mode defines tasks with different priorities to execute parts of the model code that have different sample rates.

See Multitasking and Pseudomultitasking Modes for a description of how this works. It is important to understand that section before proceeding here.

Single-Tasking Versus Multitasking Operation

Single-tasking programs require longer sample intervals, because all computations must be executed within each clock period. This can result in inefficient use of available CPU time, as shown in the previous figure.

Multitasking mode can improve the efficiency of your program if the model is large and has many blocks executing at each rate.

However, if your model is dominated by a single rate, and only a few blocks execute at a slower rate, multitasking can actually degrade performance. In such a model, the overhead incurred in 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 you have a model that can benefit from multitasking execution, you might need to modify your model by adding Rate Transition blocks (or instruct the Simulink engine to do so) to generate expected results.

For more information about the two modes of execution and examples, see Modeling for Single-Tasking Execution and Modeling for Multitasking Execution.

Related Topics