Main Content

Exchange Data Between External Calling Code and Generated Code

To export the generated code into your external code, you configure the generated code to match the data interface of your external code. For example, if your external code defines a global variable for storing output data and you need the generated code to read that data as input, you can configure a corresponding Inport block so that the generated code interacts with the existing variable.

  • You can generate reentrant code from a model. The generated entry-point functions typically accept data through arguments. Your calling code passes data through these arguments. You can call the functions multiple times in a single application—the application can maintain multiple instances of the model. See Data Exchange for Reentrant Generated Code.

  • When you generate nonreentrant code, by default, the entry-point functions exchange data between the generated code and your code through global variables. You can generate variable definitions for your code to use or you can share and reuse existing variables that your code already defines. See Data Exchange for Nonreentrant Generated Code.

    Alternatively, you can configure the entry-point functions to exchange system inputs and outputs (root-level Inport and Outport blocks) through arguments instead of global variables. Apply function prototype control to the model, which requires Embedded Coder®. For more information about function prototype control, see Configure C Code Generation for Model Entry-Point Functions.

For general information about exchanging data between generated and external code, including how to match specific C code patterns, see Exchange Data Between External C/C++ Code and Simulink Model or Generated Code.

Data Exchange for Reentrant Generated Code

When you generate reentrant code, the model entry-point functions exchange data through arguments. You can control some of the characteristics of the arguments. For more information, see Control Data and Function Interface in Generated Code.

For information about creating a separate set of data for each call site in your external code, see Modify Static Main to Allocate and Access Model Instance Data.

Data Exchange for Nonreentrant Generated Code

To make the generated code read or write to an item of signal, state, or parameter data as a global variable, apply a storage class to the data in the model. The storage class also determines whether the generated code exports the variable definition to your external code or imports the definition from your code. For general information about controlling the data interface of a model that you configure to generate nonreentrant code, see Control Data Interface for Nonreentrant Code. For examples, see Design Data Interface by Configuring Inport and Outport Blocks and Integrate External Application Code with Code Generated from PID Controller.

When you generate code that defines (allocates memory for) global data, the generated code exports that data. When your external code defines data, the generated code imports that data. Typically, storage classes that import data have the word Import in the storage class name, for example, ImportedExternPointer.

Control File Placement of Exported Global Data (Embedded Coder)

When you export data from the generated code by using storage classes, the code generator creates an extern declaration. By default, this declaration typically appears in the generated header file model.h. You can include (#include) this header file in your external code.

By default, the definition (memory allocation) of exported data typically appears in model.c.

You can control the file placement of the declarations and definitions to:

  • Create separate object files that store only global parameter data.

  • Modularize the generated code by organizing declarations into separate files.

For more information about controlling file placement of declarations and definitions, see Control Placement of Global Data Definitions and Declarations in Generated Files. For an example, see Definition, Initialization, and Declaration of Parameter Data.

Prevent Duplicate Initialization Code for Global Variables

When your external code defines global variables, you can generate code that interacts with those variables. For example, use the storage class ImportFromFile (see Choose Storage Class for Controlling Data Representation in Generated Code).

For imported variables that represent signal or state data, the code generator can produce initialization code as described in Initialization of Signal, State, and Parameter Data in the Generated Code. If your code already initializes a variable, consider preventing the generation of duplicate initialization code. Create your own storage class and, for that storage class, set Data initialization to None. For information about creating and applying your own storage class, see Define Storage Classes, Memory Sections, and Function Templates for Software Architecture.

Protect Global Data with Keywords const and volatile

When your external code and the generated code exchange data through global variables, you can generate code that uses C type qualifiers const and volatile to protect data integrity and improve the safety of your application. For example:

  • Apply const to a calibration parameter.

  • Apply volatile to a global variable that stores the output of a hardware device operating asynchronously.

  • Apply const and volatile to signals, states, and parameters that represent data defined by your external code. Then, the generated code declares and interacts with the external data by using the corresponding storage type qualifiers.

You must have Embedded Coder. For more information, see Protect Global Data with const and volatile Type Qualifiers.

Related Topics