Main Content

Prepare a Control Algorithm Model for C Code Generation

Generate code for a control algorithm model, integrate the generated code with an existing system, and validate simulation and executable results.

Understand the Model

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.

Understand the Functional Design of the 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.

Inspect the Top-Level Model

Open the example model.

The top-level model consists of:

  • Four subsystems: PI_ctrl_1, PI_ctrl_2, Define_Throt_Param, and Pos_Command_Arbitration.

  • Top-level inputs: pos_rqst, fbk_1, and fbk_2.

  • Top-level outputs: pos_cmd_one, pos_cmd_two, and ThrotComm.

  • Signal routing.

  • 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.

Inspect Subsystems

Two subsystems represent PI controllers: PI_ctrl_1 and 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.

Open the subsystem PI_ctrl_1.

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 fail_safe position.

Open Pos_Command_Arbitration.

Inspect Model Configuration Parameter Settings for Code Generation

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:

  • Execution efficiency

  • ROM efficiency

  • RAM efficiency

  • Traceability

  • Safety precaution

  • Debugging

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:

  • Solver

  • Hardware Implementation

  • Code Generation

Solver

Open the Solver pane.

  • To generate code for a model, you must set model configuration parameter Type to Fixed-step.

  • 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.

Hardware Implementation

Open the Hardware Implementation pane.

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.

Code Generation

Open the Code Generation pane.

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

  • Hardware-specific targets

Make file

Code optimizations

  • 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

  • C files

  • H files

  • Object files

  • Folder paths

Generation of ASAP2 files

Save Model Configuration Parameters

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);

Understand the Simulation Testing Environment

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

Open the test harness.

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

Highlight the unit under test.

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 (rtwdemo_PCG_Eval_P1).

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.

Highlight the test vector source.

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.

Highlight Verification.

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.

load_system('rtwdemo_PCGEvalHarness')
open_system('rtwdemo_PCGEvalHarness/Verification')

Highlight the plant/feedback system.

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.

Highlight scaled input and output.

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.

Run Simulation Tests

To run the test harness model simulation, click Start or click this hyperlink.

Run the test harness.

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.

sim('rtwdemo_PCGEvalHarness')

The lower-right plot shows the difference between the expected (golden) throttle position and the throttle position that the plant calculated.

Generate Code

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:

Generate code for the model.

The code generator produces several files. The resulting code, though computationally efficient, is not yet organized for integration into the production environment.

Examine the Generated Code

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 Model Explorer, open the HTML Code Browser.

In the generated code, observe that:

  • The controller code exists in one function called ModelName_step, which is in the file rtwdemo_PCG_Eval_P1.c.

  • The code generator folds the operations of multiple blocks into one statement of code.

  • The function ModelName_initialize initializes variables.

  • Data structures define model data (for example, rtwdemo_PCG_Eval_P1_U.pos_rqst).

  • 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.

Related Topics