You can customize code that the code generator produces for a model by specifying external code with custom code blocks or model configuration parameters.
Place code at the start and end of the generated code for the root model.
Place declaration, body, and exit code in generated function code for blocks in the root model or nonvirtual subsystems.
The functions that you can augment with external code depends on the functions that the code generator produces for blocks that are in the model. For example, if a model or atomic subsystem includes blocks that have states, you can specify code for a disable function. Likewise, if you need the code for a block to save data, free memory, or reset target hardware, specify code for a terminate function. For more information, see Block Target File Methods.
To place external C or C++ code at specific locations in code that the code generator produces for root models and subsystems, iterate through the tasks listed in this table.
Task | Action | More Information |
---|---|---|
1 | If you want to integrate external C code with generated C++ code or conversely, modify the language of the external code to match the language choice for the generated code. | Modify Programming Language of External Code to Match Generated Code |
2 | Review your assessment of external code characteristics and integration requirements. | Choose an External Code Integration Workflow |
3 | If necessary, rewrite code in C or C++. | |
4 | Choose an integration approach to add the external code to a Simulink model. | Choose an Integration Approach |
5 | Define the representation of model data for code generation. | Exchange Data Between External C/C++ Code and Simulink Model or Generated Code |
6 | Configure the model for code generation. | Generate Code That Matches Appearance of External Code and Model Configuration |
7 | Generate code and a code generation report. | Code Generation |
8 | Review the generated code interface and static code metrics. | Analyze the Generated Code Interface and Static Code Metrics |
9 | Build an executable program from the model. | Build Integrated Code Within the Simulink Environment |
10 | Verify that executable program performs as expected. | Numerical Equivalence Testing and Code Execution Profiling |
Within the Simulink® modeling environment, two approaches are available for placing external C or C++ code into sections of code that the code generator produces:
Add blocks from the Custom Code library to a root model or atomic subsystem.
Set model configuration parameters on the Code Generation > Custom Code pane.
The following table compares the two approaches. Choose the approach that aligns best with your integration requirements. For more information about how to apply each approach, see Integrate External Code by Using Custom Code Blocks and Integrate External Code by Using Model Configuration Parameters.
Requirement | Blocks | Model Configuration Parameters |
---|---|---|
Include a representation of your external code in the modeling canvas | ✓ | |
Place code in functions generated for root models | ✓ | ✓ |
Place code in functions generated for atomic subsystems | ✓ | |
Save code placement in a model configuration set | ✓ | |
Place code at the top and bottom of the header and source files generated for a model | ✓ | ✓ |
Place code within declaration, execution, and exit sections
of the SystemInitialize andSystemTerminate functions
that the code generator creates | ✓ | ✓ |
Place code within declaration, execution, and exit sections
of the SystemStart , SystemEnable , SystemDisable , SystemOutputs , SystemUpdate ,
orSystemDerivatives functions that the code generator
creates | ✓ | |
Add preprocessor macro definitions to generated code | ✓ | |
Use the custom code settings that are specified for the simulation target | ✓ | |
Configure a library model to use custom code settings of the parent model to which the library is linked | ✓ |
The Custom Code block library contains blocks that you can use
to place external C or C++ code into specific locations and functions
within code that the code generator produces. The library consists
of 10 blocks that add your code to the model header (model
.h
)
and source (model
.c
or model
.cpp
)
files that the code generator produces.
The Model Header and Model Source blocks add external code at the top and bottom of header and source files that the code generator produces for a root model. These blocks display two text fields into which you can type or paste code. One field specifies code that you want to place at the top of the generated header or source file. The second field specifies code that you want to place at the bottom of the file.
The remaining blocks add external code to functions that the code generator produces for the root model or atomic subsystem that contains the block. The blocks display text fields into which you can type or paste code that customizes functions that the code generator produces. The text fields correspond to the declaration, execution, and exit sections of code for a given function.
To Customize Code That | Use This Block |
---|---|
Computes continuous states | System Derivatives |
Disables state | System Disable |
Enables state | System Enable |
Resets state | System Initialize |
Produces output | System Outputs |
Executes once | System Start |
Saves data, free memory, reset target hardware | System Terminate |
Requires updates at each major time step | System Update |
The block and its location within a model determines where the
code generator places the external code. For example, if the System
Outputs block is at the root model level, the code generator
places the code in the model Outputs
function.
If the block resides in a triggered or enabled subsystem, the code
generator places the code in the subsystem Outputs
function.
If the code generator does not need to generate a function that corresponds to a Custom Code block that you include in a model, the code generator does one of the following:
Omits the external code that you specify in the Custom Code block.
Returns an error, indicating that the model does not include a relevant block. In this case, remove the Custom Code block from the model.
For more information, see Block Target File Methods.
Note
To avoid a potential mismatch between simulation and code generation results, do not use custom code blocks to read from and write to global Simulink data (signals, states, and block parameters). Instead, use the proper modeling pattern (for example, Data Store Read, Data Store Write, State Reader, and State Writer blocks.)
To add the Custom Code library blocks to a model:
In the Simulink Library Browser, open the Custom Code block library.
Drag the blocks that you want into your model or subsystem. Drag Model Header and Model Source blocks into root models only. Drag function-based Custom Code blocks into root models or atomic subsystems.
You can use models that contain Custom Code blocks as referenced models. The code generator ignores the blocks when producing code for a simulation target. When producing code for a code generation target, the code generator includes and compiles the custom code.
This example shows how to use the System Start block to place external C code in the code that the code generator produces for a model that includes a discrete filter.
Create the following model.
Configure the model for code generation.
Double-click the System Start block.
In the block parameters dialog box, in the System Start Function Declaration Code field, enter this code:
unsigned int *ptr = 0xFFEE;
In the System Start Function Execution Code field, enter this code:
/* Initialize hardware */ *ptr = 0;
Click OK.
Generate code and a code generation report.
View the generated
file.
Search for the string model
.cstart function
. You should
find the following code, which includes the external code that you
entered in steps 4 and 5.
{ { /* user code (Start function Header) */ /* System '<Root>' */ unsigned int *ptr = 0xFFEE; /* user code (Start function Body) */ /* System '<Root>' */ /* Initialize hardware */ *ptr = 0; } }
For another example, see Integrate External C Code Into Generated Code By Using Custom Code Blocks and Model Configuration Parameters.
Model configuration parameters provide a way to place external C or C++ code into specific locations and functions within code that the code generator produces.
To | Select |
---|---|
Insert external code near the top of the generated or file | Source file, and enter the external code to insert. If
you generate subsystem code into separate files, that code does
not have access to external code that you specify with the
Source file parameter. For example, if
you specify an include file as a Source
file setting, the code generator inserts the
|
Insert external code near the top of the generated file | Header file, and enter the external code to insert. |
Insert external code inside the model initialize function in
the or file | Initialize function, and enter the external code to insert. |
Insert external code inside the model terminate function in
the or file | Terminate function, and enter the external code to insert. Also select the Terminate function required parameter on the Interface pane. |
Add preprocessor macro definitions | Defines, and enter a space-separated list
of preprocessor macro definitions to add to the generated code. The
list can include simple definitions (for example, -DEF1 )
and definitions with a value (for example, -DDEF2=1 ).
Definitions can omit the -D (for example, -DFOO=1 and FOO=1 are
equivalent). If a definition includes -D , the toolchain
can override the flag if the toolchain uses a different flag for defines. |
Use the same custom code parameter settings as the settings specified for simulation of MATLAB Function blocks, Stateflow® charts, and Truth Table blocks | Use the same custom code settings as Simulation Target This parameter refers to the Simulation Target pane in the Configuration Parameters dialog box. |
Enable a library model to use custom code settings unique from the parent model to which the library is linked | Use local custom code settings (do not inherit from main model) This parameter is available only for library models that contain MATLAB Function blocks, Stateflow charts, or Truth Table blocks. |
To include a header file in an external header file, add #ifndef
code.
Using this code avoids multiple inclusions. For example, in rtwtypes.h
,
the following #include
guards are added:
#ifndef RTW_HEADER_rtwtypes_h_ #define RTW_HEADER_rtwtypes_h_ ... #endif /* RTW_HEADER_rtwtypes_h_ */
For more information on how to add files names and locations of header, source, and shared library files to the build process, see Build Integrated Code Within the Simulink Environment.
Note
The code generator includes external code that you include in a configuration set when generating code for software-in-the-loop (SIL) and processor-in-the-loop (PIL) simulations. However, the code generator ignores external code that you include in a configuration set when producing code with the S-function, rapid simulation, or simulation system target file.
For more information about Custom Code parameters, see Model Configuration Parameters: Code Generation Custom Code. For an example, see Integrate External C Code Into Generated Code By Using Custom Code Blocks and Model Configuration Parameters.
This example shows how to place external code in generated code by using custom code blocks and model configuration parameters.
1. Open the model rtwdemo_slcustcode
.
open_system('rtwdemo_slcustcode')
2. Open the Simulink Coder or Embedded Coder app.
3. Open the Model Configuration Parameters dialog box and navigate to the Custom Code pane.
4. Examine the settings for model configuration parameters Source file and Initialize function.
Source file specifies a comment and sets the variable GLOBAL_INT2
to -1.
Initialize function initializes the variable GLOBAL_INT2
to 1.
5. Close the dialog box.
6. Double-click the Model Source block. Block parameter Top of Model Source specifies that the code generator declare the variable GLOBAL_INT1
and set it to 0 at the top of the generated file rtwdemo_slcustcode.c
.
7. Open the triggered subsystem Amplifier
. The subsystem includes the System Outputs block. The code generator places code that you specify in that block in the generated code for the nearest parent atomic subsystem. In this case, the code generator places the external code in the generated code for the Amplifier
subsystem. The external code:
Declares the pointer variable *intPtr
and initializes it with the value of variable GLOBAL_INT1
.
Sets the pointer variable to -1 during execution.
Resets the pointer variable to 0 before exiting.
8. Generate code and a code generation report.
9. Examine the code in the generated source file rtwdemo_slcustcode.c
. At the top of the file, after the #include
statements, you find the following declaration code. The example specifies the first declaration with the Source file configuration parameter and the second declaration with the Model Source block.
int_T GLOBAL_INT2 = -1;
int_T GLOBAL_INT1 = 0;
The Output function for the Amplifier
subsystem includes the following code, which shows the external code integrated with generated code that applies the gain. The example specifies the three lines of code for the pointer variable with the System Outputs block in the Amplifier
subsystem.
int_T *intPtr = &GLOBAL_INT1;
*intPtr = -1;
rtwdemo_slcustcode_Y.Output = rtwdemo_slcustcode_U.Input << 1;
*intPtr = 0;
The following assignment appears in the model initialize entry-point function. The example specifies this assignment with the Initialize function configuration parameter.
GLOBAL_INT2 = 1;