Main Content

Write Code to Interact with Generated C API Signal Code

In this step of the example, you generate model code that contains C API elements for model signals. Then you write external code that can interact with it.

Open the model CapiSigsParams.

capiMdl = "CapiSigsParams";
open_system(capiMdl);

CapiSigsParams model

Generate Model Code and Verify That Signals Are Included in C API

Use the slbuild command to generate code from your model. Use evalc to suppress the output of the slbuild command.

evalc("slbuild(capiMdl,GenerateCodeOnly=true)");

The C API structure array that corresponds to model signals is rtBlockSignals. To view the instantiation code for this structure, examine the generated C API source file CapiSigsParams_capi.c (located in the folder CapiSigsParams_grt_rtw).

This is the instantiation code for the structure in this file:

/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 0, 0, TARGET_STRING("CapiSigsParams/Amplifier_1"),
    TARGET_STRING("mySig1"), 0, 0, 0, 0, 0 },

  { 1, 0, TARGET_STRING("CapiSigsParams/Amplifier_2"),
    TARGET_STRING("mySig2"), 0, 0, 0, 0, 0 },

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

Write Code to Interact with C API Signals Code

The C function exploreCapiSignals is defined in the file CapiSigsParams_03.c (located in the folder CapiSigsParamsFiles) and interacts with the generated C API model code. It uses the C API interface to access metadata of model signals:

  1. The main C API map is a field of an inner structure of the real-time model object. From the real-time model object, the function gets a pointer to the main C API map.

  2. The function gets the pointer to the static C API map, which is a field in the main C API map.

  3. The number of signals in the model and the pointer to signal map array are two of the fields of the Signal structure, which is an inner structure in the static C API map. The function gets the pointer to the signal map array.

  4. From the signal map array, the function gets and prints the names of the model signals.

To view the exploreCapiSignals function, examine the file CapiSigsParams_03.c.

/** exploreCapiSignals **
 * Use the C API to obtain and to print the number of signals in the model and their names.
 */
void exploreCapiSignals()
{
  /* Get a pointer to the main C API map from the real-time object: */
  rtwCAPI_ModelMappingInfo *mainCapiMap = &CapiSigsParams_M->DataMapInfo.mmi;

  /* Get a pointer to the main C API static map: */
  rtwCAPI_ModelMappingStaticInfo *capiStaticMap = mainCapiMap->staticMap;

  /* Get the number of signals in the model: */
  int sigCount = (capiStaticMap->Signals).numSignals;

  /* Get the pointer to the signal structure array. */
  const rtwCAPI_Signals *capiSigArr = (capiStaticMap->Signals).signals;

  /* Print the number of signals in the model and their names: */
  printf("There are %i signals in the model: ",sigCount);
  for(int idx=0 ; idx<sigCount ; idx++)
  {
    printf(capiSigArr[idx].signalName);
    if(idx < sigCount-1)
    {
      printf(" , ");
    }
  }
  printf(".\n");
} 
/* End exploreCapiSignals */

The figure shows the relationships of the data structures in the exploreCapiSignals function.

Schematic representation of model and C API data structures, and their inter-relations. The main C API model map is shown as a field in the real-time model object. A pointer to the static C API map is shown as a field in the main map. A pointer to the C API signal array is shown as a field in Signals, which is an inner structure of the static map

Instruct the code generator to compile CapiSigsParams_03.c along with the model and invoke the exploreCapiSignals function during the initialization stage of the model code execution. To do this, specify this custom code information:

Specified Information

Custom Code Instruction

Where the function is declared

Include header directive

Where the function is defined

Source file path

When and how to invoke the function

Add function invocation code to model initialization code

Store these custom code information instructions in variables.

includeHeaderDirective = '# include "CapiSigsParamsFiles/CapiSigsParamsDemo.h"';
srcFilePath = "CapiSigsParamsFiles/CapiSigsParams_03.c";
addInitCode = "exploreCapiSignals();";

To add these code generation instructions:

  1. Open the Configuration Parameters dialog box.

  2. Navigate to the Code Generation > Custom Code pane.

  3. In the Custom code settings section, select the Code Information tab and enter the include header directive and source file path in the Include headers and Source files boxes, respectively.

  4. Select the Additional source code tab and enter the call to the exploreCapiModelElements in the Initialize code box.

  5. Click OK.

Configuration Parameters dialog box. The Code Generation > Custom Code pane is open. In the Code information tab of the Custom code settings section, the include header directive is specified in the Include headers box as '# include "CapiSigsParamsFiles/CapiSigsParamsDemo.h"'

Alternatively, you can specify these parameters programmatically by entering these commands in the Command Window:

set_param(capiMdl,CustomHeaderCode=includeHeaderDirective)
set_param(capiMdl,CustomSource=srcFilePath)
set_param(capiMdl,CustomInitializer=addInitCode)

Generate and Run Model Code

Use the slbuild command to generate code from your model. Use evalc to suppress the output of the slbuild command.

evalc("slbuild(capiMdl,GenerateCodeOnly=false)");

The code generator generates a standalone executable from the model. Use the system command to run this executable with the "-echo" input argument so that you can see the output of the model executable, with the printing from the exploreCapiModelElements function.

system(capiMdl,"-echo");
/bin/bash: line 1: CapiSigsParams: command not found

In the next step of the example, your external C code interacts with the generated C API signal code throughout execution of the generated code. To continue to the next step of the example, use this in the Command Window:

openExample("simulinkcoder/CapiSigsParams04Example")