To use the code that you generate from a model, you call generated entry-point functions
initialize. The calling environment and
the generated functions exchange input and output data through global variables or through
formal parameters (arguments). This data and the exchange mechanisms constitute the interfaces
of the entry-point functions. For information about the default interfaces for reentrant and
nonreentrant models in the generated code, see How Generated Code Exchanges Data with an Environment.
By controlling the interfaces that appear in the generated code, you can:
Minimize the modifications that you must make to existing code.
Generate stable interfaces that do not change or minimally change when you make changes to the model.
Generate code that exchanges data more efficiently (for example, by using pointers and pass-by-reference arguments for nonscalar data).
By default, for nonreentrant code, Inport blocks at the root level of the model appear in the generated code as fields of a global structure variable. Similarly, Outport blocks appear in a different structure. For reentrant code, depending on your setting for model configuration parameter Pass root-level I/O, the code generator can also package input and output data into standard structures.
With Embedded Coder®, you can control these names. See Control Characteristics of Data Structures (Embedded Coder).
To use the generated code, you write code that calls generated entry-point functions.
For example, entry-point functions include
, and top-level functions
generated from an export-function model. To control the names of the model entry-point
functions, use the Code Mappings editor (requires Embedded Coder) to apply a combination of these techniques:
On the Function Defaults tab, specify default naming rules for categories of entry-point functions by applying function customization templates in the Code Mappings editor. With this technique, a naming rule applies to functions in a category. For more information, see Configure Default Code Generation for Functions.
On the Functions tab, specify names for individual entry-point functions by either directly editing the Function Name column or through a configuration dialog box opened from the Function Preview column. Names that you specify override default naming rules specified by function customization templates. For more information, see Configure C Code Generation for Model Entry-Point Functions
When you set the model configuration parameter Code interface
Nonreusable function (the default),
generated entry-point functions are not reentrant. Typically, the functions exchange data
with the calling environment through direct access to global variables.
To remove the block from the standard I/O structures by creating a separate global
variable, apply a storage class, such as
ExportToFile, to the signal that the block represents. You can
configure a default storage class for categories of data elements, such as
Inport blocks. As you add such blocks to the model, they acquire the
storage class that you specify. You can use the Code Mappings editor also to configure
individual blocks. You might do this if a model has just a few data elements of a
specific category or override the default configuration settings.
For an example, see Design Data Interface by Configuring Inport and Outport Blocks. For general information about configuring data for code generation, see C Code Generation Configuration for Model Interface Elements.
If your calling code already defines a global variable that you want the generated
code to use as input data or use to store output data, you can reuse the variable by
preventing the code generator from duplicating the definition. Apply a storage class to
the corresponding Inport or Outport block in the model.
Choose a storage class that specifies an imported data scope, such as
ImportFromFile. For information
about applying storage classes, see C Code Generation Configuration for Model Interface Elements and Organize Parameter Data into a Structure by Using Struct Storage Class.
You can configure a single Inport or Outport block to appear in the generated code as a custom structure that contains multiple input or output signals. You can also configure the block to appear as a substructure of the default I/O structures or as a separate structure variable.
Configure the block as a nonvirtual bus by using a
object as the data type of the block. If your external code defines the structure type,
consider using the
Simulink.importExternalCTypes function to generate
the bus object.
To generate the bus signal as a substructure in the standard I/O structures,
leave the block storage class at the default setting,
you have Embedded Coder, in the Code Mappings editor, on the Data
Defaults tab, set the storage class for categories
Inports and Outports to
To generate the bus signal as a separate global structure variable, apply a
storage class such as
For more information about grouping signals into custom structures in the generated code, see Organize Data into Structures in Generated Code.
If your external code defines a function that returns input data for the generated
code or accepts output data that the generated code produces, you can configure an
Inport or Outport block so that the generated code calls
the function instead of accessing a global variable. Apply the Embedded Coder storage class
GetSet. For more information, see Access Data Through Functions with Storage Class GetSet.
With Embedded Coder, you can optionally configure the model step (execution) function to access root-level input and output through arguments instead of directly reading and writing to global variables. Completely control the argument characteristics such as name, order, and passing mechanism (by reference or by value). This level of configuration can help to integrate generated code with your external code.
To pass inputs and outputs through arguments, in the Configure C Step Function interface dialog box, select Configure arguments for Step function prototype. Each Inport and Outport block at the root level of the model appears in the code as an argument of the execution function. For more information, see Configure C Code Generation for Model Entry-Point Functions.
By default, for a nonreentrant referenced model, the generated code passes root-level
input and output through function arguments. A nonreentrant referenced model is one in
which you set model configuration parameter Total number of instances allowed
per top model to
To pass this data through global variables instead (for a
interface), in the referenced model, apply storage classes such as
ExportToFile to root-level
Inport and Outport blocks.
To apply a default storage class to such blocks, use the Code Mapping Editor.
With this technique, as you add such blocks to the model, the blocks acquire the
default storage class, preserving the
void-void interface. For
more information, see Configure Default Code Generation for Data.
To override the default storage class, apply storage classes directly to individual blocks by using the Code Mapping editor. See C Code Generation Configuration for Model Interface Elements.
For an example that requires Embedded Coder, see Establish Data Ownership in a Model Hierarchy.
When you set Code interface packaging to
function, generated entry-point functions are reentrant. The functions
exchange data with the calling environment through formal parameters (arguments). By
default, each root-level Inport and Outport block appears in
the generated code as a separate argument instead of a field of the standard I/O
Some changes that you make to a model change the entry-point function interfaces in the generated code. For example, if you change the name of the model, the names of the functions can change. If you configure the model code to exchange data through arguments, when you add or remove Inport or Outport blocks or change the names of the blocks, the corresponding arguments can change.
For easier maintenance of your calling code, prevent changes to the interfaces of the entry-point functions.
If you exchange input and output data through arguments, configure the generated code to package Inport and Outport blocks into structures instead of allowing each block to appear as a separate argument (the default). Then, when you add or remove Inport or Outport blocks, or change their properties such as name and data type, the fields of the structures change, but the function interfaces do not change. See Reduce Number of Arguments by Using Structures.
Set the data types of Inport and Outport blocks explicitly instead of using an inherited data type setting (which these blocks use by default). Inherited data type settings can cause the blocks to use different data types depending on the data types of upstream and downstream signals. For more information about configuring data types, see Control Signal Data Types.
With Embedded Coder, specify function names that do not depend on the model name. If you
specify a naming rule with a function customization template, do not use the token
$R in the rule. See Control Names of Generated Entry-Point Functions (Embedded Coder).
Reducing the number of arguments of a function can improve the readability of the code and reduce consumption of stack memory. To create a structure argument that can pass multiple pieces of data at one time, use these techniques:
Manually combine multiple Inport or Outport blocks so that they appear in the generated code as fields of a structure or substructure of a standard data structure. The generated entry-point function or functions accept the address of the structure as a separate argument or as a substructure (field) of the standard I/O structures.
Replace the Inport or Outport blocks with a single
block, and configure the new block as a nonvirtual bus by using a
Simulink.Bus object as the data type of the block. If your external
code defines the structure type, consider using the
Simulink.importExternalCTypes function to generate the bus
object. See Organize Data into Structures in Generated Code and
When you generate reentrant code with Embedded Coder, configure Inport and Outport blocks to
appear in aggregated structures by default. Set model configuration parameter
Pass root-level I/O as to a setting other than
To package Inport and Outport blocks into the
real-time model data structure, select
Part of model data
structure. The code generator aggregates the blocks into the
default I/O structures to which the real-time model data structure points. The
generated entry-point function or functions accept the real-time model data
structure as a single argument. If you choose this setting, the function has the
smallest number of arguments.
To aggregate Inport blocks into a structure and
Outport blocks into a different structure, select
Structure reference. The generated entry-point
function or functions accept the address of each structure as an argument.
Another argument accepts the real-time model data structure. If you choose this
setting, the inputs and outputs are more identifiable in the function
With this setting, if you remove the root-level Inport blocks or the root-level Outport blocks, the function signature can change. Similarly, the signature can change if you add a root-level Inport or Outport block to a model that does not include such blocks.
For more control over the characteristics of the structures, set
Pass root-level I/O as to
Part of model data
structure. Then, set the default storage class for
Inport and Outport blocks to a structured
storage class that you create. With this technique:
You can create a single structure for the blocks or create two separate structures.
You can control the names of the structure types.
The structures appear as substructures of the real-time model data
structure. You must set Pass root-level I/O as to
Part of model data structure.
Create the storage class by using the Embedded Coder Dictionary (see Define Storage Classes, Memory Sections, and Function Templates for Software Architecture). Apply the storage class by using the Code Mappings editor (see Configure Default Code Generation for Data).
For more information, see Pass root-level I/O as.
You can configure the generated entry-point functions to exchange data through
arguments. For a scalar or array argument, to control the name of the primitive data type,
Simulink.AliasType object to either set the data type of the
corresponding block or to configure data type replacements for the entire model. These
techniques require Embedded Coder. For more information, see Control Data Type Names in Generated Code.
By default, the code generator assumes that Inport and Outport blocks at the root level of the model constitute the data interface of the model. You can promote an arbitrary signal, block parameter, or block state to the interface so that other systems and components can access it. See Promote Internal Data to the Interface.