Exchange Data Between External C/C++ Code and Simulink Model or Generated Code - MATLAB & Simulink (original) (raw)
Whether you import your external code into a Simulink® model or export the generated code to an external environment, the model or the generated code typically exchange data (signals, states, and parameters) with your code.
Functions in C or C++ code, including your external functions, can exchange data with a caller or a called function through:
- Arguments (formal parameters) of functions. When a function exchanges data through arguments, an application can call the function multiple times. Each instance of the called function can manipulate its own independent set of data so that the instances do not interfere with each other.
- Direct access to global variables. Global variables can:
- Enable different algorithms (functions) and instances of the same algorithm to share data such as calibration parameters and error status.
- Enable the different rates (functions) of a multitasking system to exchange data.
- Enable different algorithms to exchange data asynchronously.
In Simulink, you can organize and configure data so that a model uses these exchange mechanisms to provide, extract, and share data with your code.
Before you attempt to match data interfaces, to choose an overall integration approach, see Choose an External Code Integration Workflow.
Import External Code into Model
To exchange data between your model and your external function, choose an exchange mechanism based on the technique that you chose to integrate the function.
- To exchange data through the arguments of your external function, construct and configure your model to create and package the data according to the data types of the arguments. Then, you connect and configure the block that calls or represents your function to accept, produce, or refer to the data from the model.
For example, if you use the S-Function Builder to generate anS-Function block that calls your function, the ports and parameters of the block correspond to the arguments of the function. You connect the output signals of upstream blocks to the input ports and set parameter values in the block mask. Then, you can create signal lines from the output ports of the block and connect those signals to downstream blocks. - To exchange data through global variables that your external code already defines, a best practice is to use a Stateflow® chart to call your function and to access the variables. You write algorithmic C code in the chart so that during simulation or execution of the generated code, the model reads and writes to the variables.
To use such a global variable as an item of parameter data (not signal or state data) elsewhere in a model, you can create a numeric MATLAB® variable orSimulink.Parameter
object that represents the variable. If you change the value of the C-code variable in between simulation runs, you must manually synchronize the value of the Simulink variable or object. If your algorithmic code (function) changes the value of the C-code variable during simulation, the corresponding Simulink variable or object does not change.
If you choose to create a Simulink representation of the C-code variable, you can configure the Simulink representation so that the generated code reads and writes to the variable but does not duplicate the variable definition. Apply a storage class to the Simulink representation.
Export Generated Code to External Environment
To export the generated code into your external code, see Exchange Data Between External Calling Code and Generated Code.
Simulink Representations of C Data Types and Constructs
To model and reuse your custom C data such as structures, enumerations, andtypedef
aliases, use the information in these tables.
Modeling Patterns for Matching Data in External C Code
C Data Type or Construct | Example C Code | Simulink Equivalent | More Information |
---|---|---|---|
Primitive type alias (typedef) | typedef float mySinglePrec_T; | Create a Simulink.AliasType object. Use the object to: Set the data types of signals and block parameters in a model.Configure data type replacements for code generation. Generating code that uses an alias data type requires Embedded Coder®. | For information about defining custom data types for your model, see Simulink.AliasType and Manage Replacement of Simulink Data Types in Generated Code. For an example that shows how to export the generated code into your external code, see Replace and Rename Simulink Coder Data Types to Conform to Coding Standards. |
Array | int myArray[6]; | Specify signal and parameter dimensions as described inDetermine Signal Dimensions.The generated code defines and accesses multidimensional data, including matrices, as column-major serialized vectors. If your external code uses a different format, consider using alternative techniques to integrate the generated code. SeeCode Generation of Matrices and Arrays. | For information about how the generated code stores nonscalar data (including limitations), see Code Generation of Matrices and Arrays.For an example that shows how to export the generated code into your external code, see Reuse Parameter Data in Different Data Type Contexts.To model lookup tables, see Simulink.LookupTable. |
Enumeration | typedef enum myColorsType { Red = 0, Yellow, Blue } myColorsType; | Define a Simulink enumeration that corresponds to your enumeration definition. Use the Simulink enumeration to set data types in a model. | To use enumerated data in a Simulink model, see Use Enumerated Data in Generated Code.For an example that shows how to generate enumerated parameter data, see Enumeration.For an example that shows how to export the generated code into your external code by exchanging enumerated data, see Exchange Structured and Enumerated Data Between Generated and External Code. |
Structure | typedef struct myStructType { int count; double coeff; } myStructType; | Create a Simulink.Bus object that corresponds to your structure type. To create structured signal or state data, package multiple signal lines in a model into a single nonvirtual bus signal. To create structured parameter data, create a parameter object (such as Simulink.Parameter) that stores a MATLAB structure. Use the bus object as the data type of the parameter object. To package lookup table data into a structure, use Simulink.LookupTable and, optionally, Simulink.Breakpoint objects. | For information about bus signals, see Group Signals or Messages into Virtual Buses. For information about structures of parameters, see Organize Related Block Parameter Definitions in Structures.For an example that shows how to import your external code into a model by using the Legacy Code Tool, seeIntegrate C Function Whose Arguments Are Pointers to Structures.For examples that show how to export the generated code into your external code, see Exchange Structured and Enumerated Data Between Generated and External Code and Access Structured Data Through a Pointer That External Code Defines.To package lookup table data into a structure, Simulink.LookupTable.For general information about creating structures in the generated code, seeOrganize Data into Structures in Generated Code. |
Additional Modeling Patterns for Code Generation (Embedded Coder)
C Data Type or Construct | Example C Code | Simulink Equivalent | More Information |
---|---|---|---|
Macro | #define myParam 9.8 | Apply the storage classes Define andImportedDefine to parameters. With macros, you can reuse a parameter value in multiple locations in an algorithm and change the parameter value between code compilations without consuming memory to store the value. Typically, macros represent engineering constants that you do not expect to change during code execution.This technique requires Embedded Coder. | Macro Definitions (#define) |
Storage type qualifiers such as const andvolatile | const myParam = 9.8; | Apply the storage classes Const,Volatile, andConstVolatile to data items. | Protect Global Data with Keywords const and volatile |
Bit field | typedef struct myBitField { unsigned short int MODE : 1; unsigned short int FAIL : 1; unsigned short int OK : 1; } myBitField | Apply the storage classBitField to signals, states, and parameters whose data type isboolean, fixed-point, or integer.Use a model configuration parameter to aggregate Boolean data into bit fields. These techniques require Embedded Coder. | BitfieldsOptimize Generated Code by Packing Boolean Data into Bitfields |
Call to custom external function that reads or writes to data | External code: /* Call this function to acquire the value of the signal. */ double get_inSig(void) { return myBigGlobalStruct.inSig; } Generated algorithmic code: algorithmInput = get_inSig(); | Apply the storage class GetSet to signals, states, and parameters. Each data item appears in the generated code as a call to your custom functions that read and write to the target data.This technique requires Embedded Coder. | Access Data Through Functions with Storage Class GetSet |
Considerations for Other Modeling Goals
Goal | Considerations and More Information |
---|---|
Use Simulink to run and interact with the generated code | You can use SIL, PIL, and external mode simulations to connect your model to the corresponding generated application for simulation. When you import parameter data from your external code: At the time that you begin an external mode simulation, the external executable uses the value that your code uses to initialize the parameter data. However, when you change the corresponding value in Simulink during the simulation (for example by modifying the Value property of the corresponding parameter object), Simulink downloads the new value to the executable.SIL and PIL simulations do not import the parameter value from your code. Instead, the simulations use the parameter value from Simulink. If you include your external code in the Simulink Coder™ build process, duplicate data definitions can prevent the generated code from compiling.For information about SIL and PIL, see Choose a SIL or PIL Approach. For information about external mode simulation, see External Mode Simulations for Parameter Tuning, Signal Monitoring, and Code Execution Profiling. |
Generate code comments that describe attributes of exported data including physical units, real-world initial value, and data type | Generating these comments can help you match data interfaces while handwriting integration code. See Add Custom Comments for Variables in the Generated Code. |
Related Topics
- How Generated Code Exchanges Data with an Environment
- Generate Code That Matches Appearance of External Code
- Design Data Interface by Configuring Inport and Outport Blocks
- Configure Generated Code According to Interface Control Document Specifications
- Generate Code That Dereferences Data from a Literal Memory Address