Generate code for a control algorithm model, integrate the generated code with an existing system, and validate simulation and executable results.
This example shows and describes the model from behavioral and structural perspectives. The example also shows how to configure a model for code generation and how to generate code. You learn how to:
Understand the functional behavior of the example model.
Understand how to validate the model.
Become familiar with model-checking tools.
Become familiar with configuration options that affect code generation.
Generate code from a model.
This example uses a simple model of a throttle controller. The model features redundancy, which safety-critical, drive-by-wire applications commonly use. The model highlights a standard model structure and a set of basic blocks in algorithm design.
In the current configuration, the code that the model generates is not configured for a production target system. In this example, you change the target configuration and observe the resulting changes to the format of the generated code.
The top-level model consists of:
No transformative blocks. Transformative blocks change the value of a signal, for example, Sum and Integrator blocks.
The layout shows a basic model architectural style.
Separation of calculations from signal routing (lines and buses)
Partitioning into subsystems
This style suits many types of models.
Two subsystems represent PI controllers:
PI_ctrl_2. The subsystems have identical content and, for now, use identical data. Later, you use the subsystems to learn how the code generator can create reusable functions.
The PI controllers come from a library, which is a group of related blocks or models that you intend to reuse. Libraries provide one of two methods for including and reusing models. You see the second method, model referencing, later in this series.
When you use a library block in a model, you cannot edit the instance of the block in the model. Instead, edit the block definition in the library. Then, instances of the block in different models remain consistent.
The Stateflow® chart
Pos_Command_Arbitration performs basic error checking on the two command signals. If the command signals are too far apart, the chart sets the output to a
To prepare a model for code generation, open the Embedded Coder app. Then, set code generation model configuration parameters. The parameters determine the method that the code generator uses to generate the code and the resulting code format.
Code Generation Objectives
You can manually configure the model configuration parameters. Alternatively, you can choose from predefined objectives to automatically configure the model configuration parameters.
You can choose from these high-level code generation objectives:
Each objective checks the current model configuration parameters against the recommended values of the objectives. Each objective also includes a set of Code Generation Advisor checks. You can use these additional checks to verify that the model configuration parameters are set to create code that meets the objectives.
Some of the recommendations that the objectives make conflict with the Code Generation Advisor checks. The order in which you select objectives determines the result. Simulink® resolves conflicts by satisfying objectives that have a higher priority.
The figure shows how to set the priority to
Execution efficiency >
ROM efficiency >
RAM efficiency. To open the dialog box, in the Configuration Parameters dialog box, select the Code Generation pane. Then, click Set objectives.
You can run the Code Generation Advisor to check the model based on the specified objectives. To open the Code Generation Advisor, in the C Code tab, click C/C++ Code Advisor.
The Code Generation Advisor creates a list of checks based on the objectives that you select. The first check reviews current values of the model configuration parameters and suggests alternative values based on the objectives. The check provides an automated method for setting the parameters to recommended values.
Manual Configuration Options
In the Model Configuration Parameters dialog box, these panes are relevant to code generation:
To generate code for a model, you must set model configuration parameter Type to
Parameter Fixed-step size sets the base rate of the system. Set the parameter to the lowest common multiple of rates in the system.
Parameter Solver controls the integration algorithms that the code generator uses.
To generate an entry-point function for each rate in the system, select parameter Treat each discrete rate as a separate task.
Use hardware implementation parameters to specify a hardware board. Simulink® adjusts other settings on the pane, including hidden microprocessor device details, based on your board selection. To view or adjust the hidden parameter settings, such as the word size and byte ordering, click Device details.
Use the Code Generation pane to specify the system target file and optimizations. This example uses the Embedded Coder® system target file (
ert.tlc). You can extend that system target file to create a customized configuration. Some of the basic parameters on the Code Generation pane and its subpanes include:
System target file
ert.tlc - "Base" Embedded Coder®
grt.tlc - "Base" Generic Real-Time Target
Remove unused branches from the code and control the creation of temporary variables.
Control which signals have explicit initialization code.
Enable and disable use of overflow and division-by-zero protection code.
Code formatting options
Use of parentheses
Header file information
Variable naming conventions
Inclusion of custom code
Generation of ASAP2 files
You can save the values of model configuration parameters as a MATLAB® function. At the command prompt, enter:
hCs = getActiveConfigSet('rtwdemo_PCG_Eval_P1'); hCs.saveAs('ConfiguredData');
The MATLAB® function saves a textual representation of the configuration parameter object. You can use the generated file for archiving or comparing different versions of the files by using traditional diff tools. You can also visually inspect the content of the file.
You can run the function to set the configuration parameters of other models.
hCs2 = ConfiguredData; attachConfigSet('myModel', hCs2, true); setActiveConfigSet('myModel', hCs2.Name);
You test the throttle controller model in a separate model called a test harness. A test harness is a model that evaluates the control algorithm. Using a test harness:
Separates the test data from the control algorithm
Separates the plant or feedback model from the control algorithm
Provides a reusable environment for multiple versions of the control algorithm
A typical simulation testing environment consists of these parts:
Unit under test
Test vector source
Evaluation and logging
Plant or feedback system
Input and output scaling
The control algorithm is the unit under test. The test harness model references the control algorithm through a Model block. With Model blocks, you can reuse components. The Model block refers to the control algorithm by name (
The Model block enables inclusion (referencing) of a model in another model as a compiled function. By default, Simulink® compiles the referenced model when you change it. Compiled functions have these advantages over libraries:
Large models simulate faster.
You can simulate compiled functions directly.
The simulation requires less memory. When you add multiple instances of the model (multiple Model blocks), only one copy of the compiled model exists in memory.
The model uses a Signal Builder block as the test vector source. The block has data that drives the simulation (
pos_rqst) and the expected results that the Verification subsystem uses. This example uses only one set of test data, though in a typical application you create a test suite that fully exercises the system.
The test harness compares the simulation results against golden data, which is a set of test results that indicate the desired behavior for the model. In this model, the V&V Assertion block compares the simulated throttle value position from the plant against the golden value that the test harness provides. If the difference between the two signals is greater than 5%, the test fails and the Assertion block stops the simulation.
Alternatively, you can evaluate the simulation data after the simulation completes execution. You can use either MATLAB® scripts or third-party tools to perform the evaluation. Post-execution evaluation provides greater flexibility in the analysis of the data, though you must wait until execution finishes. Combining the two methods can yield a highly flexible and efficient test environment.
This example models the throttle dynamics by breaking a transfer function down into a canonical form. You can create plant models to model a specific level of fidelity. Many applications use a different plant model at each stage of testing.
The subsystems that scale input and output perform these primary functions:
Select signals to route to the unit under test and to the plant.
Rescale signals between engineering units and units that the unit under test requires.
Handle rate transitions between the plant and the unit under test.
To run the test harness model simulation, click Start or click this hyperlink.
The first time the test harness runs, Simulink® must compile the referenced model. You can monitor the compilation progress in the Command Window.
When the model simulation is complete, Simulink® displays the results in a plot figure.
The lower-right plot shows the difference between the expected (golden) throttle position and the throttle position that the plant calculated.
To generate code, open the Embedded Coder app. Then, using one of these techniques:
In the model, press Ctrl+B.
In the C Code tab, select Build or Generate Code.
Click this hyperlink:
The code generator produces several files. The resulting code, though computationally efficient, is not yet organized for integration into the production environment.
The code generator creates multiple files that you can view from the Code view or code generation report. In addition to the standard C definition and header files, the code generator creates a set of HTML files. The HTML files provide hyperlinks between the code and the model.
In the generated code, observe that:
The controller code exists in one function called
ModelName_step, which is in the file
The code generator folds the operations of multiple blocks into one statement of code.
ModelName_initialize initializes variables.
Data structures define model data (for example,
rtwdemo_PCG_Eval_P1.c: C file that defines step and initialization functions
ert_main.c: Example Main file that includes a simple scheduler
rtwdemo_PCG_Eval_P1.h: H file that contains type definitions of the Simulink® Coder™ data structures
PCG_Eval_p1_private.h: File that declares data that only the generated code uses
rtwdemo_PCG_Eval_P1_types.h: H file that declares the real-time model data structure
For the next example in this series, see Configure Data Interface in the Generated Code.