Main Content

Place External C/C++ Code in Generated Code

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.

Workflow

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.

TaskActionMore Information
1If 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
2Review your assessment of external code characteristics and integration requirements.Choose an External Code Integration Workflow
3If necessary, rewrite code in C or C++. 
4Choose an integration approach to add the external code to a Simulink model.Choose an Integration Approach
5Define the representation of model data for code generation.Exchange Data Between External C/C++ Code and Simulink Model or Generated Code
6Configure the model for code generation.Generate Code That Matches Appearance of External Code and Model Configuration
7Generate code and a code generation report.Code Generation
8Review the generated code interface and static code metrics.Analyze the Generated Code Interface and Static Code Metrics
9Build an executable program from the model.Build Integrated Code Within the Simulink Environment
10Verify that executable program performs as expected.Numerical Equivalence Testing and Code Execution Profiling

Choose an Integration Approach

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.

RequirementBlocksModel 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 

Integrate External Code by Using Custom Code Blocks

Custom Code Block Library

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 ThatUse This Block
Computes continuous statesSystem Derivatives
Disables state System Disable
Enables stateSystem Enable
Resets stateSystem Initialize
Produces outputSystem Outputs
Executes onceSystem Start
Saves data, free memory, reset target hardwareSystem Terminate
Requires updates at each major time stepSystem 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.)

Add Custom Code Blocks to the Modeling Canvas

To add the Custom Code library blocks to a model:

  1. In the Simulink Library Browser, open the Custom Code block library.

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

Add External Code to Generated Start Function

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.

  1. Create the following model.

  2. Configure the model for code generation.

  3. Double-click the System Start block.

  4. In the block parameters dialog box, in the System Start Function Declaration Code field, enter this code:

    unsigned int *ptr = 0xFFEE;
  5. In the System Start Function Execution Code field, enter this code:

    /* Initialize hardware */
    *ptr = 0;
  6. Click OK.

  7. Generate code and a code generation report.

  8. View the generated model.c file. Search for the string start 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.

Integrate External Code by Using 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.

ToSelect
Insert external code near the top of the generated model.c or model.cpp 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 #include near the top of the model.c or model.cpp file. The subsystem code that the code generator places in a separate file does not have access to declarations inside your included file. In this case, consider specifying your external code with the Header file parameter.

Insert external code near the top of the generated model.h fileHeader file, and enter the external code to insert.
Insert external code inside the model initialize function in the model.c or model.cpp fileInitialize function, and enter the external code to insert.
Insert external code inside the model terminate function in the model.c or model.cpp fileTerminate 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.

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;

Related Topics