Main Content

Exchange Data Between Generated and External Code Using C API

Some Simulink® Coder™ applications must interact with signals, states, root-level inputs/outputs, or parameters in the generated code for a model. For example, calibration applications monitor and modify parameters. Signal monitoring or data logging applications interface with signal, state, and root-level input/output data. Using the Simulink Coder C API, you can build target applications that log signals, states, and root-level inputs/outputs, monitor signals, states, and root-level inputs/outputs, and tune parameters, while the generated code executes.

The C API minimizes its memory footprint by sharing information common to signals, states, root-level inputs/outputs, and parameters in smaller structures. Signal, state, root-level input/output, and parameter structures include an index into the structure map, allowing multiple signals, states, root-level inputs/outputs, or parameters to share data.

To get started with an example, see Use C API to Access Model Signals and States or Use C API to Access Model Parameters.

Generated C API Files

When you configure a model to use the C API, the Simulink Coder code generator generates two additional files, model_capi.c (or .cpp) and model_capi.h, where model is the name of the model. The code generator places the two C API files in the build folder, based on settings in the Configuration Parameters dialog box. The C API source code file contains information about global block output signals, states, root-level inputs/outputs, and global parameters defined in the generated code model source code. The C API header file is an interface header file between the model source code and the generated C API. You can use the information in these C API files to create your application. Among the files generated are those shown in the next figure.

Generated Files with C API Selected

Note

When you configure the code generator to produce code that includes support for the C API interface and data logging, the code generator can include text for block names in the block paths logged to C API files model_capi.c (or .cpp) and model_capi.h. If the text includes characters that are unrepresented in the character set encoding for the model, the code generator replaces the characters with XML escape sequences. For example, the code generator replaces the Japanese full-width Katakana letter ア with the escape sequence ア. For more information, see Internationalization and Code Generation.

Generate C API Files

To generate C API files for your model:

  1. Select the C API interface for your model. There are two ways to select the C API interface for your model, as described in the following sections.

  2. Generate code for your model.

After generating code, you can examine the files model_capi.c (or .cpp) and model_capi.h in the model build folder.

Select C API with Configuration Parameters Dialog

  1. Open your model, and open the Configuration Parameters dialog box.

  2. In the Code Generation > Interface pane, in the Data exchange interface subgroup, select one or more C API options. Based on the options you select, support for accessing signals, parameters, states, and root-level I/O will appear in the C API generated code.

    • If you want to generate C API code for global block output signals, select Generate C API for: signals.

    • If you want to generate C API code for global block parameters, select Generate C API for: parameters.

    • If you want to generate C API code for discrete and continuous states, select Generate C API for: states.

    • If you want to generate C API code for root-level inputs and outputs, select Generate C API for: root-level I/O.

Select C API from the Command Line

From the MATLAB® command line, you can use the set_param function to select or clear C API model configuration parameters. At the MATLAB command line, enter one or more of the following commands, where modelname is the name of your model.

To select Generate C API for: signals, enter:

set_param('modelname','RTWCAPISignals','on')

To clear Generate C API for: signals, enter:

set_param('modelname','RTWCAPISignals','off')

To select Generate C API for: parameters, enter:

set_param('modelname','RTWCAPIParams','on')

To clear Generate C API for: parameters, enter:

set_param('modelname','RTWCAPIParams','off')

To select Generate C API for: states, enter:

set_param('modelname','RTWCAPIStates','on')

To clear Generate C API for: states, enter:

set_param('modelname','RTWCAPIStates','off')

To select Generate C API for: root-level I/O, enter:

set_param('modelname','RTWCAPIRootIO','on')

To clear Generate C API for: root-level I/O, enter:

set_param('modelname','RTWCAPIRootIO','off')

Description of C API Files

About C API Files

The model_capi.c (or .cpp) file provides external applications with a consistent interface to model data. Depending on your configuration settings, the data could be a signal, state, root-level input or output, or parameter. In this document, the term data item refers to either a signal, a state, a root-level input or output, or a parameter. The C API uses structures that provide an interface to the data item properties. The interface packages the properties of each data item in a data structure. If the model contains multiple data items, the interface generates an array of data structures. The members of a data structure map to data properties.

To interface with data items, an application requires the following properties for each data item:

  • Name

  • Block path

  • Port number (for signals and root-level inputs/outputs only)

  • Address

  • Data type information: native data type, data size, complexity, and other attributes

  • Dimensions information: number of rows, number of columns, and data orientation (scalar, vector, matrix, or n-dimensional)

  • Fixed-point information: slope, bias, scale type, word length, exponent, and other attributes

  • Sample-time information (for signals, states, and root-level inputs/outputs only): sample time, task identifier, frames

As illustrated in the next figure, the properties of data item A, for example, are located in data structure DS_A. The properties of data item B are located in data structure DS_B.

Some property values can be unique to each data item, and there are some property values that several data items can share in common. Name, for example, has a unique value for each data item. The interface places the unique property values directly in the structure for the data item. The name value of data item A is in DS_A, and the name value of data item B is in DS_B.

But data type could be a property whose value several data items have in common. The ability of some data items to share a property allows the C API to have a reuse feature. In this case, the interface places only an index value in DS_A and an index value in DS_B. These indices point to a different data structure, DS_C, that contains the actual data type value. The next figure shows this scheme with more detail.

The figure shows three signals. signal1 and signal2 share the same data type, double. Instead of specifying this data type value in each signal data structure, the interface provides only an index value, 0, in the structure. "double" is described by entry 0 in the rtDataTypeMap array, which is referenced by both signals. Additionally, property values can be shared between signals, states, root-level inputs/outputs, and parameters, so states, root-level inputs/outputs, and parameters also might reference the double entry in the rtDataTypeMap array. This reuse of information reduces the memory size of the generated interface.

Structure Arrays Generated in C API Files

As with data type, the interface maps other common properties (such as address, dimension, fixed-point scaling, and sample time) into separate structures and provides an index in the structure for the data item. For a complete list of structure definitions, refer to the file matlabroot/rtw/c/src/rtw_capi.h. This file also describes each member in a structure. The structure arrays generated in the model_capi.c (or .cpp) file are of structure types defined in the rtw_capi.h file. Here is a brief description of the structure arrays generated in model_capi.c (or .cpp):

  • rtBlockSignals is an array of structures that contains information about global block output signals in the model. Each element in the array is of type struct rtwCAPI_Signals. The members of this structure provide the signal name, block path, block port number, address, and indices to the data type, dimension, fixed-point, and sample-time structure arrays.

  • rtBlockParameters is an array of structures that contains information about the tunable block parameters in the model by block name and parameter name. Each element in the array is of type struct rtwCAPI_BlockParameters. The members of this structure provide the parameter name, block path, address, and indices to data type, dimension, and fixed-point structure arrays.

  • rtBlockStates is an array of structures that contains information about discrete and continuous states in the model. Each element in the array is of type struct rtwCAPI_States. The members of this structure provide the state name, block path, type (continuous or discrete), and indices to the address, data type, dimension, fixed-point, and sample-time structure arrays.

  • rtRootInputs is an array of structures that contains information about root-level inputs in the model. Each element in the array is of type struct rtwCAPI_Signals. The members of this structure provide the root-level input name, block path, block port number, address, and indices to the data type, dimension, fixed-point, and sample-time structure arrays.

  • rtRootOutputs is an array of structures that contains information about root-level outputs in the model. Each element in the array is of type struct rtwCAPI_Signals. The members of this structure provide the root-level output name, block path, block port number, address, and indices to the data type, dimension, fixed-point, and sample-time structure arrays.

  • rtModelParameters is an array of structures that contains information about workplace variables that one or more blocks or Stateflow® charts in the model reference as block parameters. Each element in the array is of data type rtwCAPI_ModelParameters. The members of this structure provide the variable name, address, and indices to data type, dimension, and fixed-point structure arrays.

  • rtDataAddrMap is an array of base addresses of signals, states, root-level inputs/outputs, and parameters that appear in the rtBlockSignals, rtBlockParameters, rtBlockStates, and rtModelParameters arrays. Each element of the rtDataAddrMap array is a pointer to void (void*).

  • rtDataTypeMap is an array of structures that contains information about the various data types in the model. Each element of this array is of type struct rtwCAPI_DataTypeMap. The members of this structure provide the data type name, size of the data type, and information on whether or not the data is complex.

  • rtDimensionMap is an array of structures that contains information about the various data dimensions in the model. Each element of this array is of type struct rtwCAPI_DimensionMap. The members of this structure provide information on the number of dimensions in the data, the orientation of the data (whether it is scalar, vector, or a matrix), and the actual dimensions of the data.

  • rtFixPtMap is an array of structures that contains fixed-point information about the signals, states, root-level inputs/outputs, and parameters. Each element of this array is of type struct rtwCAPI_FixPtMap. The members of this structure provide information about the data scaling, bias, exponent, and whether or not the fixed-point data is signed. If the model does not have fixed-point data (signal, state, root-level input/output, or parameter), the Simulink Coder software assigns NULL or zero values to the elements of the rtFixPtMap array.

  • rtSampleTimeMap is an array of structures that contains sampling information about the global signals, states, and root-level inputs/outputs in the model. (This array does not contain information about parameters.) Each element of this array is of type struct rtwCAPI_SampleTimeMap. The members of this structure provide information about the sample period, offset, and whether or not the data is frame-based or sample-based.

Generate Example C API Files

Subtopics C API Signals, C API States, C API Root-Level Inputs and Outputs, and C API Parameters discuss generated C API structures using the example model CAPIPModel. To generate code from the example model, do the following:

  1. Open the model.

    openExample('CAPIModel')

  2. If you want to generate C API structures for root-level inputs/outputs in CAPIModel, select model configuration parameter Generate C API for: root-level I/O.

    The setting this parameter must match between the top model and the referenced model. If you modify the parameter setting, save the top model and the referenced model to the same writable work folder.

  3. Generate code for the model.

The C API code examples in the next subtopics are generated with C as the target language.

This model has three global block output signals that will appear in C API generated code:

  • top_sig1, which is a test point at the output of the Gain1 block in the top model

  • sig2_eg, which appears in the top model and is defined in the base workspace as a Simulink.Signal object having storage class ExportedGlobal

  • bot_sig1, which appears in the referenced model CAPIModelRef and is defined as a Simulink.Signal object having storage class Model default

The model also has two discrete states that will appear in the C API generated code:

  • top_state, which is defined for the Delay1 block in the top model

  • bot_state, which is defined for the Discrete Filter block in the referenced model

The model has root-level inputs/outputs that will appear in the C API generated code if you select model configuration parameter Generate C API for: root-level I/O:

  • Four root-level inputs, In1 through In4

  • Six root-level outputs, Out1 through Out6

Additionally, the model has five global block parameters that will appear in C API generated code:

  • Kp (top model Gain1 block and referenced model Gain2 block share)

  • Ki (referenced model Gain3 block)

  • p1 (lookup table lu1d)

  • p2 (lookup table lu2d)

  • p3 (lookup table lu3d)

C API Signals

The rtwCAPI_Signals structure captures signal information including the signal name, address, block path, output port number, data type information, dimensions information, fixed-point information, and sample-time information.

Here is the section of code in CAPIModel_capi.c that provides information on C API signals for the top model in CAPIModel:

/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 0, 0, "CAPIModel/Gain1",
    "top_sig1", 0, 0, 0, 0, 0 },

  { 1, 0, "CAPIModel/lu2d",
    "sig2_eg", 0, 0, 1, 0, 0 },

  {
    0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
  }
};

Note

To better understand the code, read the comments in the file. For example, notice the comment that begins on the third line in the preceding code. This comment lists the members of the rtwCAPI_Signals structure, in order. This tells you the order in which the assigned values for each member appear for a signal. In this example, the comment tells you that signalName is the fourth member of the structure. The following lines describe the first signal:

  { 0, 0, "CAPIModel/Gain1",
    "top_sig1", 0, 0, 0, 0, 0 },

From these lines you infer that the name of the first signal is top_sig1.

Each array element, except the last, describes one output port for a block signal. The final array element is a sentinel, with all elements set to null values. For example, examine the second signal, described by the following code:

  { 1, 0, "CAPIModel/lu2d",
    "sig2_eg", 0, 0, 1, 0, 0 },

This signal, named sig2_eg, is the output signal of the first port of the block CAPIModel/lu2d. (This port is the first port because the zero-based index for portNumber displayed on the second line is assigned the value 0.)

The address of this signal is given by addrMapIndex, which, in this example, is displayed on the first line as 1. This provides an index into the rtDataAddrMap array, found later in CAPIModel_capi.c:

/* Declare Data Addresses statically */
static void* rtDataAddrMap[] = {
  &CAPIModel_B.top_sig1,               /* 0: Signal */
  &sig2_eg[0],                         /* 1: Signal */
  &CAPIModel_DWork.top_state,          /* 2: Discrete State */
  &rtP_Ki,                             /* 3: Model Parameter */
  &rtP_Kp,                             /* 4: Model Parameter */
  &rtP_p1[0],                          /* 5: Model Parameter */
  &rtP_p2[0],                          /* 6: Model Parameter */
  &rtP_p3[0],                          /* 7: Model Parameter */
};

The index of 1 points to the second element in the rtDataAddrMap array. From the rtDataAddrMap array, you can infer that the address of this signal is &sig2_eg[0].

This level of indirection supports multiple code instances of the same model. For multiple instances, the signal information remains constant, except for the address. In this case, the model is a single instance. Therefore, the rtDataAddrMap is declared statically. If you choose to generate reusable code, an initialize function is generated that initializes the addresses dynamically per instance. For details on generating reusable code, see Configure Generated C Function Interface for Model Entry-Point Functions and see Configure Code Reuse Support (Embedded Coder).

The dataTypeIndex provides an index into the rtDataTypeMap array, found later in CAPIModel_capi.c, indicating the data type of the signal:

/* Data Type Map - use dataTypeMapIndex to access this structure */
static const rtwCAPI_DataTypeMap rtDataTypeMap[] = {
  /* cName, mwName, numElements, elemMapIndex, dataSize, slDataId, *
   * isComplex, isPointer */
  { "double", "real_T", 0, 0, sizeof(real_T), SS_DOUBLE, 0, 0 }
};

Because the index is 0 for sig2_eg, the index points to the first structure element in the array. You can infer that the data type of the signal is double. The value of isComplex is 0, indicating that the signal is not complex. Rather than providing the data type information directly in the rtwCAPI_Signals structure, a level of indirection is introduced. The indirection allows multiple signals that share the same data type to point to one map structure, saving memory for each signal.

The dimIndex (dimensions index) provides an index into the rtDimensionMap array, found later in CAPIModel_capi.c, indicating the dimensions of the signal. Because this index is 1 for sig2_eg, the index points to the second element in the rtDimensionMap array:

/* Dimension Map - use dimensionMapIndex to access elements of ths structure*/
static const rtwCAPI_DimensionMap rtDimensionMap[] = {
  /* dataOrientation, dimArrayIndex, numDims, vardimsIndex */
  { rtwCAPI_SCALAR, 0, 2, 0 },

  { rtwCAPI_VECTOR, 2, 2, 0 },
...
};

From this structure, you can infer that this is a nonscalar signal having a dimension of 2. The dimArrayIndex value, 2, provides an index into rtDimensionArray, found later in CAPIModel_capi.c:

/* Dimension Array- use dimArrayIndex to access elements of this array */
static const uint_T rtDimensionArray[] = {
  1,                                   /* 0 */
  1,                                   /* 1 */
  2,                                   /* 2 */
...
};

The fxpIndex (fixed-point index) provides an index into the rtFixPtMap array, found later in CAPIModel_capi.c, indicating fixed-point information about the signal. Your code can use the scaling information to compute the real-world value of the signal, using the equation V=SQ+B, where V is “real-world” (that is, base-10) value, S is user-specified slope, Q is “quantized fixed-point value” or “stored integer,” and B is user-specified bias. For details, see Scaling (Fixed-Point Designer).

Because this index is 0 for sig2_eg, the signal does not have fixed-point information. A fixed-point map index of zero means that the signal does not have fixed-point information.

The sTimeIndex (sample-time index) provides the index to the rtSampleTimeMap array, found later in CAPIModel_capi.c, indicating task information about the signal. If you log multirate signals or conditionally executed signals, the sampling information can be useful.

Note

model_capi.c (or .cpp) includes rtw_capi.h. A source file that references the rtBlockSignals array also must include rtw_capi.h.

C API States

The rtwCAPI_States structure captures state information including the state name, address, block path, type (continuous or discrete), data type information, dimensions information, fixed-point information, and sample-time information.

Here is the section of code in CAPIModel_capi.c that provides information on C API states for the top model in CAPIModel:

/* Block states information */
static const rtwCAPI_States rtBlockStates[] = {
  /* addrMapIndex, contStateStartIndex, blockPath,
   * stateName, pathAlias, dWorkIndex, dataTypeIndex, dimIndex,
   * fixPtIdx, sTimeIndex, isContinuous
   */
  { 2, -1, "CAPIModel/Delay1",
    "top_state", "", 0, 0, 0, 0, 0, 0 },

  {
    0, -1, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0
  }
};

Each array element, except the last, describes a state in the model. The final array element is a sentinel, with all elements set to null values. In this example, the C API code for the top model displays one state:

  { 2, -1, "CAPIModel/Delay1",
    "top_state", "", 0, 0, 0, 0, 0, 0 },

This state, named top_state, is defined for the block CAPIModel/Delay1. The value of isContinuous is zero, indicating that the state is discrete rather than continuous. The other fields correspond to the like-named signal equivalents described in C API Signals, as follows:

  • The address of the signal is given by addrMapIndex, which, in this example, is 2. This is an index into the rtDataAddrMap array, found later in CAPIModel_capi.c. Because the index is zero based, 2 corresponds to the third element in rtDataAddrMap, which is &CAPIModel_DWork.top_state.

  • The dataTypeIndex provides an index into the rtDataTypeMap array, found later in CAPIModel_capi.c, indicating the data type of the parameter. The value 0 corresponds to a double, noncomplex parameter.

  • The dimIndex (dimensions index) provides an index into the rtDimensionMap array, found later in CAPIModel_capi.c. The value 0 corresponds to the first entry, which is { rtwCAPI_SCALAR, 0, 2, 0 }.

  • The fixPtIndex (fixed-point index) provides an index into the rtFixPtMap array, found later in CAPIModel_capi.c, indicating fixed-point information about the parameter. As with the corresponding signal attribute, a fixed-point map index of zero means that the parameter does not have fixed-point information.

C API Root-Level Inputs and Outputs

The rtwCAPI_Signals structure captures root-level input/output information including the input/output name, address, block path, port number, data type information, dimensions information, fixed-point information, and sample-time information. (This structure also is used for block output signals, as previously described in C API Signals.)

Here is the section of code in CAPIModel_capi.c that provides information on C API root-level inputs/outputs for the top model in CAPIModel:

/* Root Inputs information */
static const rtwCAPI_Signals rtRootInputs[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 3, 0, "CAPIModel/In1",
    "", 1, 0, 0, 0, 0 },

  { 4, 0, "CAPIModel/In2",
    "", 2, 0, 0, 0, 0 },

  { 5, 0, "CAPIModel/In3",
    "", 3, 0, 0, 0, 0 },

  { 6, 0, "CAPIModel/In4",
    "", 4, 0, 0, 0, 0 },

  {
    0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
  }
};

/* Root Outputs information */
static const rtwCAPI_Signals rtRootOutputs[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 7, 0, "CAPIModel/Out1",
    "", 1, 0, 0, 0, 0 },

  { 8, 0, "CAPIModel/Out2",
    "", 2, 0, 0, 0, 0 },

  { 9, 0, "CAPIModel/Out3",
    "", 3, 0, 0, 0, 0 },

  { 10, 0, "CAPIModel/Out4",
    "", 4, 0, 0, 0, 0 },

  { 11, 0, "CAPIModel/Out5",
    "sig2_eg", 5, 0, 1, 0, 0 },

  { 12, 0, "CAPIModel/Out6",
    "", 6, 0, 1, 0, 0 },

  {
    0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
  }
};

Note

When you generate C++ code, the code generator does not provide information on C API root-level inputs/outputs.

For information about interpreting the values in the rtwCAPI_Signals structure, see the previous section C API Signals.

C API Parameters

The rtwCAPI_BlockParameters and rtwCAPI_ModelParameters structures capture parameter information including the parameter name, block path (for block parameters), address, data type information, dimensions information, and fixed-point information.

The rtModelParameters array contains entries for workspace variables that are referenced as tunable Simulink block parameters or Stateflow data of machine scope. For example, tunable parameters include Simulink.Parameter objects that use a storage class other than Auto. The Simulink Coder software assigns its elements only NULL or zero values in the absence of such data.

The setting that you select for the model configuration parameter Default parameter behavior determines how information is generated into the rtBlockParameters array in model_capi.c (or .cpp).

  • If you set Default parameter behavior to Tunable, the rtBlockParameters array contains an entry for every modifiable parameter of every block in the model. However, if you use a MATLAB variable or a tunable parameter to specify a block parameter, the block parameter does not appear in rtBlockParameters. Instead, the variable or tunable parameter appears in rtModelParameters.

  • If you set Default parameter behavior to Inlined, the rtBlockParameters array is empty. The Simulink Coder software assigns its elements only NULL or zero values.

The last member of each array is a sentinel, with all elements set to null values.

Here is the rtBlockParameters array that is generated by default in CAPIModel_capi.c:

/* Individual block tuning is not valid when inline parameters is *
 * selected. An empty map is produced to provide a consistent     *
 * interface independent  of inlining parameters.                 *
 */
static const rtwCAPI_BlockParameters rtBlockParameters[] = {
  /* addrMapIndex, blockPath,
   * paramName, dataTypeIndex, dimIndex, fixPtIdx
   */
  {
    0, (NULL), (NULL), 0, 0, 0
  }
};

In this example, only the final, sentinel array element is generated, with all members of the structure rtwCAPI_BlockParameters set to NULL and zero values. This is because Default parameter behavior is set to Inlined by default for the CAPIModel example model. If you set Default parameter behavior to Tunable, the block parameters are generated in the rtwCAPI_BlockParameters structure. However, MATLAB variables and tunable parameters appear in the rtwCAPI_ModelParameters structure.

Here is the rtModelParameters array that is generated by default in CAPIModel_capi.c:

/* Tunable variable parameters */
static const rtwCAPI_ModelParameters rtModelParameters[] = {
  /* addrMapIndex, varName, dataTypeIndex, dimIndex, fixPtIndex */
  { 2, TARGET_STRING("Ki"), 0, 0, 0 },

  { 3, TARGET_STRING("Kp"), 0, 0, 0 },

  { 4, TARGET_STRING("p1"), 0, 2, 0 },

  { 5, TARGET_STRING("p2"), 0, 3, 0 },

  { 6, TARGET_STRING("p3"), 0, 4, 0 },

  { 0, (NULL), 0, 0, 0 }
};

In this example, the rtModelParameters array contains entries for each variable that is referenced as a tunable Simulink block parameter.

For example, the varName (variable name) of the fourth parameter is p2. The other fields correspond to the like-named signal equivalents described in C API Signals, as follows:

  • The address of the fourth parameter is given by addrMapIndex, which, in this example, is 5. This is an index into the rtDataAddrMap array, found later in CAPIModel_capi.c. Because the index is zero based, 5 corresponds to the sixth element in rtDataAddrMap, which is rtP_p2.

  • The dataTypeIndex provides an index into the rtDataTypeMap array, found later in CAPIModel_capi.c, indicating the data type of the parameter. The value 0 corresponds to a double, noncomplex parameter.

  • The dimIndex (dimensions index) provides an index into the rtDimensionMap array, found later in CAPIModel_capi.c. The value 3 corresponds to the fourth entry, which is { rtwCAPI_MATRIX_COL_MAJOR, 6, 2, 0 }.

  • The fixPtIndex (fixed-point index) provides an index into the rtFixPtMap array, found later in CAPIModel_capi.c, indicating fixed-point information about the parameter. As with the corresponding signal attribute, a fixed-point map index of zero means that the parameter does not have fixed-point information.

For more information about tunable parameter storage in the generated code, see How Generated Code Stores Internal Signal, State, and Parameter Data.

Map C API Data Structures to rtModel

The real-time model data structure encapsulates model data and associated information that describes the model fully. When you select the C API feature and generate code, the Simulink Coder code generator adds another member to the real-time model data structure generated in model.h:

/*
 * DataMapInfo:
 * The following substructure contains information regarding
 * structures generated in the model's C API.
 */
struct {
  rtwCAPI_ModelMappingInfo mmi;
} DataMapInfo;

This member defines mmi (for model mapping information) of type struct rtwCAPI_ModelMappingInfo. The structure is located in matlabroot/rtw/c/src/rtw_modelmap.h. The mmi substructure defines the interface between the model and the C API files. More specifically, members of mmi map the real-time model data structure to the structures in model_capi.c (or .cpp).

Initializing values of mmi members to the arrays accomplishes the mapping, as shown in Map Model to C API Arrays of Structures. Each member points to one of the arrays of structures in the generated C API file. For example, the address of the rtBlockSignals array of structures is allocated to the first member of the mmi substructure in model.c (or .cpp), using the following code in the rtw_modelmap.h file:

/* signals */
struct {
    rtwCAPI_Signals const *signals;     /* Signals Array */
    uint_T                numSignals;   /* Num Signals   */
    rtwCAPI_Signals const *rootInputs;  /* Root Inputs array */
    uint_T               numRootInputs; /* Num Root Inputs  */
    rtwCAPI_Signals const *rootOutputs; /* Root Outputs array */
    uint_T               numRootOutputs;/* Num Root Outputs  */
} Signals;

The model initialize function in model.c (or .cpp) performs the initializing by calling the C API initialize function. For example, the following code is generated in the model initialize function for example model CAPIModel:

/* Initialize DataMapInfo substructure containing ModelMap for C API */
CAPIModel_InitializeDataMapInfo(CAPIModel_M);

Map Model to C API Arrays of Structures

Note

This figure lists the arrays in the order that their structures appear in rtw_modelmap.h, which differs slightly from their generated order in model_capi.c.

Generate C API Data Definition File for Exchanging Data with a Target System

This example shows how to use the target-based C API to interface with generated code that represents signals, states, parameters, and root-level I/O.

Open Example Model

Open the example model CAPIModel.

open_system('CAPIModel');

The C API is useful for interacting with application data in generated code, without stopping program execution or recompiling the generated code. To use the C API interface, for a top model and its referenced models:

1. Set up a client/server protocol (such as TCP/IP or a dual-port memory connection) between your development computer and the target computer.

2. Select at least one of the C API model configuration parameters: signals, parameters, states, and root-level I/O.

3. Configure the data elements that you want to access with the C API with addressable storage classes.

C API configuration settings for the top model and referenced models must match.

The code generator places the C API interface in the file model_capi.c. Depending on your configuration settings, the data can represent signals, states, parameters, and root-level I/O configured with addressable storage classes. The file includes structures that provide an interface to data properties.

C API Limitations

The C API feature has the following limitations.

  • The C API does not support the following values for the CodeFormat TLC variable:

    • S-Function

    • Accelerator_S-Function (for accelerated simulation)

  • For ERT-based targets, the C API requires that support for floating-point code be enabled.

  • Local block output signals are not supported.

  • Local Stateflow parameters are not supported.

  • The following custom storage class objects are not supported:

    • Objects without the package csc_registration file

    • Grouped custom storage classes

    • Objects defined by using macros

    • BitField objects

    • FileScope objects

  • Customized data placement is disabled when you are using the C API. The interface looks for global data declaration in model.h and model_private.h. Declarations placed in any other file by customized data placement result in code that does not compile.

Note

Custom Storage Class objects work in code generation, only if you use the ERT system target file and clear the model configuration parameter Ignore custom storage classes.

Related Topics