| Real-Time Workshop® | ![]() |
| On this page… |
|---|
Rapid Prototyping Program Architecture Rapid Prototyping System-Dependent Components |
The code modules generated from a Simulink® model—model.c (or .cpp), model.h, and other files — implement the model's system equations, contain block parameters, and perform initialization.
The Real-Time Workshop® program framework provides the additional source code necessary to build the model code into a complete, standalone program. The program framework consists of application modules (files containing source code to implement required functions) designed for a number of different programming environments.
The automatic program builder ensures that the program is created with the proper modules once you have configured your template makefile. The application modules and the code generated for a Simulink model are implemented using a common API. This API defines a data structure (called a real-time model, sometimes abbreviated as rtM) that encapsulates all data for your model.
This API is similar to that of S-functions, with one major exception: the API assumes that there is only one instance of the model, whereas S-functions can have multiple instances. The function prototypes also differ from S-functions.
The structure of a real-time program consists of three components. Each component has a dependency on a different part of the environment in which the program executes. The next figure shows this structure.

The Real-Time Workshop architecture consists of three parts, the first two of which include system-dependent components and system-independent components. Together these two parts form the run-time interface.
This architecture adapts readily to a wide variety of environments by isolating the dependencies of each program component. The following sections discuss each component in more detail and include descriptions of the application modules that implement the functions carried out by the system-dependent components, system-independent components, and application components.
These components contain the program's main function, which controls program timing, creates tasks, installs interrupt handlers, enables data logging, and performs error checking.
The way in which application modules implement these operations depends on the type of computer. This means that, for example, the components used for a PC-based program perform the same operations, but differ in method of implementation from components designed to run on a VME target.
The main function in a C/C++ program is the point where execution begins. In Real-Time Workshop application programs, the main function must perform certain operations. These operations can be grouped into three categories: initialization, model execution, and program termination.
Initialize special numeric parameters rtInf, rtMinusInf, and rtNaN. These are variables that the model code can use.
Call the model registration function to get a pointer to the real-time model. The model registration function has the same name as your model. It is responsible for initializing real-time model fields and any S-functions in your model.
Initialize the model size information in the real-time model. This is done by calling MdlInitializeSizes.
Initialize a vector of sample times and offsets (for systems with multiple sample rates). This is done by calling MdlInitializeSampleTimes.
Get the model ready for execution by calling MdlStart, which initializes states and similar items.
Set up the timer to control execution of the model.
Define background tasks and enable data logging, if selected.
Execute a background task: for example, communicate with the host during external mode simulation or introduce a wait state until the next sample interval.
Execute model (initiated by interrupt).
Log data to buffer (if data logging is used).
Return from interrupt.
Call a function to terminate the program if it is designed to run for a finite time — destroy the real-time model data structure, deallocate memory, and write data to a file.
The application modules contained in the system-dependent components generally include a main module such as rt_main.c, containing the main entry point for C. There can also be additional application modules for such things as I/O support and timer handling.
These components are collectively called system independent because all environments use the same application modules to implement these operations. This section steps through the model code (and if the model has continuous states, calls one of the numerical integration routines). This section also includes the code that defines, creates, and destroys the real-time model data structure (rtM). The model code and all S-functions included in the program define their own SimStructs.
The model code execution driver calls the functions in the model code to compute the model outputs, update the discrete states, integrate the continuous states (if applicable), and update time. These functions then write their calculated data to the real-time model.
At each sample interval, the main program passes control to the model execution function, which executes one step though the model. This step reads inputs from the external hardware, calculates the model outputs, writes outputs to the external hardware, and then updates the states.
The next figure shows these steps.
Executing the Model

This scheme writes the system outputs to the hardware before the states are updated. Separating the state update from the output calculation minimizes the time between the input and output operations.
The real-time program calculates the next values for the continuous states based on the derivative vector, dx/dt, for the current values of the inputs and the state vector.
These derivatives are then used to calculate the next values of the states using a state-update equation. This is the state-update equation for the first-order Euler method (ode1)
![]()
where h is the step size of the simulation, x represents the state vector, and dx/dt is the vector of derivatives. Other algorithms can make several calls to the output and derivative routines to produce more accurate estimates.
Note, however, that real-time programs use a fixed-step size because it is necessary to guarantee the completion of all tasks within a given amount of time. This means that, while you should use higher order integration methods for models with widely varying dynamics, the higher order methods require additional computation time. In turn, the additional computation time might force you to use a larger step size, which can diminish the improvement of accuracy initially sought from the higher order integration method.
Generally, the stiffer the equations, (that is, the more dynamics in the system with widely varying time constants), the higher the order of the method that you must use.
In practice, the simulation of very stiff equations is impractical for real-time purposes except at very low sample rates. You should test fixed-step size integration in the Simulink environment to check stability and accuracy before implementing the model for use in real-time programs.
For linear systems, it is more practical to convert the model that you are simulating to a discrete time version, for instance, using the c2d function in the Control System Toolbox™ product.
The system-independent components include these modules:
ode1.c, ode2.c, ode3.c, ode4.c, ode5.c: These modules implement the integration algorithms supported for real-time applications. See Choosing a Solver in the Simulink documentation for more information about fixed-step solvers.
rt_sim.c: Performs the activities necessary for one time step of the model. It calls the model function to calculate system outputs and then updates the discrete and continuous states.
simstruc_types.h: Contains definitions of various events, including subsystem enable/disable and zero crossings. It also defines data-logging variables.
The system-independent components also include code that defines, creates, and destroys the real-time model data structure. All S-functions included in the program define their own SimStructs.
The SimStruct data structure encapsulates all the data relating to an S-function, including block parameters and outputs. See The SimStruct in the Writing S-Functions documentation for more information about SimStruct.
The application components contain the generated code for the Simulink model, including the code for any S-functions in the model. This code is referred to as the model code because these functions implement the Simulink model.
However, the generated code contains more than just functions to execute the model (as described in the previous section). There are also functions to perform initialization, facilitate data access, and complete tasks before program termination. To perform these operations, the generated code must define functions that
Create the real-time model
Initialize model size information in the real-time model
Initialize a vector of sample times and sample time offsets and store this vector in the real-time model
Store the values of the block initial conditions and program parameters in the real-time model
Compute the block and system outputs
Update the discrete state vector
Compute derivatives for continuous models
Perform an orderly termination at the end of the program (when the current time equals the final time, if a final time is specified)
Collect block and scope data for data logging (either with the Real-Time Workshop product or third-party tools)
The real-time model data structure encapsulates model data and associated information necessary to fully describe the model. Its contents include
Model parameters, inputs, and outputs
Storage areas, such as dWork
Timing information
Solver identification
Data logging information
Simstructs for all child S-functions
External mode information
The required information is stored in fields in the real-time model structure, which is defined in model.h as
/* Real-time Model Data Structure */
struct _rtModel_model_Tag {
const char *path;
const char *modelName;
struct SimStruct_tag * *childSfunctions;
const char *errorStatus;
SS_SimMode simMode;
RTWLogInfo *rtwLogInfo;
RTWExtModeInfo *extModeInfo;
RTWSolverInfo solverInfo;
RTWSolverInfo *solverInfoPtr;
void *sfcnInfo;
/*
* ModelData:
* The following substructure contains information regarding
* the data used in the model.
*/
.
.
}
The (possibly mangled) name of the model replaces model in the above tag. The individual substructures have been omitted, as they can vary.
For GRT targets, model.h also includes aliases to map global identifiers to identifiers used in prior versions (rtB, rtP, rtY, and so on). The following table lists the structure identifiers used in the generated code for these variants of the real-time model data structure. The column GRT Symbol contains the old-style (pre-Version 6) GRT identifiers, which are still used by the GRT calling interface, but not within the generated code.
Identifiers for Real-Time Model Data Structure Variants
Identifier | GRT Symbol | Data |
|---|---|---|
model_B | rtB | Block IO |
model_U | rtU | External inputs |
model_X | rtX | Continuous states |
model_Xdot | rtXdot | State derivatives |
model_Xdix | rtXdis | Continuous state disabled |
model_Y | rtY | External outputs |
model_P | rtP | Parameters |
rts | rts | Child Simstruct |
model_DWork | rtDWork | DWork |
model_ConstB | rtC | Constant block IO define, structure |
model_ConstP | rtcP | Constant parameter Structure |
model_PrevZCSigState | rtPrevZCSigState | Previous zero-crossing signal states |
model_NonsampledZC | rtNonsampledZC | Nonsampled zero-crossings |
Real-Time Workshop® Embedded Coder™ users can tailor identifiers, and can make them look like the GRT symbols listed above, should they desire such a coding style. The above GRT-ERT identifier equivalences (or at least as many of them as are required to build a given model) are established by using a set of #define macros in model.h, under the comment /* Backward compatible GRT Identifiers */.
The real-time model data structure is used for all targets. Prior to Version 5, the ERT target used the rtObject data structure, and other targets used the Simstruct data structure for encapsulating model data. Now all targets are treated the same, except for the fact that the real-time model data structure is pruned for ERT targets to save space in executables. Even when not pruned, the real-time model data structure is more space efficient than the root Simstruct used by earlier releases for non-ERT targets, as it only contains fields for child (S-function) Simstructs that are actually used in a model.
The functions defined by the model code are called at various stages of program execution (that is, initialization, model execution, or program termination).
The next figure shows the functions defined in the generated code and shows what part of the program executes each function.

The model registration function has the same name as the Simulink model from which it is generated. It is called directly by the main program during initialization. Its purpose is to initialize and return a pointer to the real-time model data structure.
A noninlined S-function is any C or C++ MEX S-function that is not implemented using a customized TLC file. If you create a C or C++ MEX S-function as part of a Simulink model, it is by default noninlined unless you write your own TLC file that inlines it within the body of the model.c or model.cpp code. The Real-Time Workshop code generator automatically incorporates your noninlined C or C++ S-functions into the program if they adhere to the S-function API described in the Simulink documentation.
This format defines functions and a SimStruct that are local to the S-function. This allows you to have multiple instances of the S-function in the model. The model's real-time model data structure contains a pointer to each S-function's SimStruct.
If a model contains S-functions, the source code for the S-function must be on the search path the make utility uses to find other source files. The directories that are searched are specified in the template makefile that is used to build the program.
S-functions are implemented in a way that is directly analogous to the model code. They contain their own public registration functions (called by the top-level model code) that initialize static function pointers in their SimStructs. When the top-level model needs to execute the S-function, it does so by using the function pointers in the S-function's SimStruct. There can be more than one S-function with the same name in your model. This is accomplished by having function pointers to static functions.
You can incorporate C/C++ MEX S-functions, along with the generated code, into the program executable. You can also write a target file for your C/C++ MEX S-function to inline the S-function, thus improving performance by eliminating function calls to the S-function itself. For more information on inlining S-functions, see the Target Language Compiler documentation.
When the Real-Time Workshop software generates code, it produces the following files:
model.c or model.cpp: C or C++ code generated from the Simulink block diagram. This code implements the block diagram's system equations as well as performing initialization and updating outputs.
model_data.c or model_data.cpp: Optional file containing data for parameters and constant block I/O, which are also declared as extern in model.h. Only generated when model_P and model_ConstB structures are populated.
model_types.h: Forward declarations for the real-time model data structure and the parameters data structure.
model.h: Header file containing the block diagram's simulation parameters, I/O structures, work structures, and other declarations.
model_private.h: Header file containing declarations of exported signals and parameters.
These files are named for the Simulink model from which they are generated.
In addition, a dummy include file always named rtmodel.h is generated, which includes the above model-specific data structures and entry points. This enables the (static) target-specific main programs to reference files generated by the Real-Time Workshop code generator without needing to know the names of the models involved.
Another dummy file, rtwtypes.h, is generated, which simply includes simstruc_types.h (only for GRT and GRT-malloc targets).
If you have created custom blocks using C/C++ MEX S-functions, you need the source code for these S-functions available during the build process.
![]() | Model Execution | Embedded Program Framework | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |