Real-Time Workshop    

Model Execution

Before looking at the two styles of generated code, you need to have a high-level understanding of how the generated model code is executed. Real-Time Workshop generates algorithmic code as defined by your model. You may include your own code into your model via S-functions. S-functions can range from high-level signal manipulation algorithms to low-level device drivers.

Real-Time Workshop also provides a run-time interface that executes the generated model code. The run-time interface and model code are compiled together to create the model executable. The diagram below shows a high-level object-oriented view of the executable.

Figure 7-1: The Object-Oriented View of a Real-Time Program

In general, the conceptual design of the model execution driver does not change between the rapid prototyping and embedded style of generated code. The following sections describe model execution for singletasking and multitasking environments both for simulation (nonreal-time) and for real-time. For most models, the multitasking environment will provide the most efficient model execution (i.e., fastest sample rate).

The following concepts are useful in describing how models execute:

The pseudocode below shows the execution of a model for a singletasking simulation (nonreal-time).

The initialization phase begins first. This consists of initializing model states and setting up the execution engine. The model then executes, one step at a time. First ModelOutputs executes at time t, then the workspace I/O data is logged, and then ModelUpdate updates the discrete states. Next, if your model has any continuous states, ModelDerivatives integrates the continuous states' derivatives to generate the states for time , where h is the step size. Time then moves forward to and the process repeats.

During the ModelOutputs and ModelUpdate phases of model execution, only blocks that have hit the current point in time execute. They determine if they have hit by using a macro (ssIsSampleHit, or ssIsSpecialSampleHit) that checks for a sample hit.

The pseudocode below shows the execution of a model for a multitasking simulation (nonreal-time).

The multitasking operation is more complex when compared with the singletasking execution because the output and update functions are subdivided by the task identifier (tid) that is passed into these functions. This allows for multiple invocations of these functions with different task identifiers using overlapped interrupts, or for multiple tasks when using a real-time operating system. In simulation, multiple tasks are emulated by executing the code in the order that would occur if there were no preemption in a real-time system.

Note that the multitasking execution assumes that all tasks are multiples of the base rate. Simulink enforces this when you have created a fixed-step multitasking model.

The multitasking execution loop is very similar to that of singletasking, except for the use of the task identifier (tid) argument to ModelOutputs and ModelUpdate. The ssIsSampleHit or ssIsSpecialSampleHit macros use the tid to determine when blocks have a hit. For example, ModelOutputs (tid=5) will execute only the blocks that have a sample time corresponding to task identifier 5.

The pseudocode below shows the execution of a model in a real-time singletasking system where the model is run at interrupt level.

Real-time singletasking execution is very similar to the nonreal-time single tasking execution, except that the execution of the model code is done at interrupt level.

At the interval specified by the program's base sample rate, the interrupt service routine (ISR) preempts the background task to execute the model code. The base sample rate is the fastest rate in the model. If the model has continuous blocks, then the integration step size determines the base sample rate.

For example, if the model code is a controller operating at 100 Hz, then every 0.01 seconds the background task is interrupted. During this interrupt, the controller reads its inputs from the analog-to-digital converter (ADC), calculates its outputs, writes these outputs to the digital-to-analog converter (DAC), and updates its states. Program control then returns to the background task. All of these steps must occur before the next interrupt.

The following pseudocode shows how a model executes in a real-time multitasking system (where the model is run at interrupt level).

Running models at interrupt level in real-time multitasking environment is very similar to the previous singletasking environment, except that overlapped interrupts are employed for concurrent execution of the tasks.

The execution of a model in a singletasking or multitasking environment when using real-time operating system tasking primitives is very similar to the interrupt-level examples discussed above. The pseudocode below is for a singletasking model using real-time tasking primitives.

In this singletasking environment, the model is executed using real-time operating system tasking primitives. In this environment, we create a single task (tSingleRate) to run the model code. This task is invoked when a clock tick occurs. The clock tick gives a clockSem (clock semaphore) to the model task (tSingleRate). The model task will wait for the semaphore before executing. The clock ticks are configured to occur at the fundamental step size (base rate) for your model.

The pseudocode below is for a multitasking model using real-time tasking primitives.

In this multitasking environment, the model is executed using real-time operating system tasking primitives. In this environment, it is necessary to create several model tasks (tBaseRate and several tSubRate tasks) to run the model code. The base rate task (tBaseRate) has a higher priority than the subrate tasks. The subrate task for tid=1 has a higher priority than the subrate task for tid=2, and so on. The base rate task is invoked when a clock tick occurs. The clock tick gives a clockSem to tBaseRate. The first thing tBaseRate does is give semaphores to the subtasks that have a hit at the current point in time. Since the base rate task has a higher priority, it continues to execute. Next it executes the fastest task (tid=0) consisting of blocks in your model that have the fastest sample time. After this execution, it resumes waiting for the clock semaphore. The clock ticks are configured to occur at executing at the fundamental step size for your model.


  Introduction Program Timing