Interact with C API Signal Code Throughout Execution
In this step of the example you write code that interacts with the generated C API signal code throughout execution of the generated code.
Open the model CapiSigsParams
.
capiMdl = "CapiSigsParams";
open_system(capiMdl);
Integrate External Code in Generated Model Code
In this step of the example you integrate three external functions into the generated model code. These functions interact with the generated C API model code while it is running. These are the three functions, which are defined in the file CapiSigsParams_04.c
:
initCapiFcn
— The code in this function initializes the data structures used by your external code. This function is invoked during the initialization of the model execution.realTimeCapiFcn
— The code in this function prints the value of the signals every 10 steps. This function is invoked in each step of the model execution.cleanCapiFcn
— The code in this function cleans up memory used by your external code. This function is invoked when model execution terminates.
Add Initialization and Termination Functions to Model Code Execution
To add the invocation of initCapiFcn
and cleanCapiFcn
you specify this custom code information:
Specified Information | Custom Code Instruction |
---|---|
Where the functions is declared | Include header directive |
Where the functions is defined | Source file path |
When to invoke | Function call to |
When to invoke | Function call to |
Store these custom code information instructions in variables.
includeHeaderDirective = '# include "CapiSigsParamsFiles/CapiSigsParamsDemo.h"'; srcFilePath = "CapiSigsParamsFiles/CapiSigsParams_04.c"; addInitCode = "initCapiFcn();"; addTerminateCode = "cleanCapiFcn();";
To add these code generation instructions:
Open the Configuration Parameters dialog box.
Navigate to the Code Generation > Custom Code pane.
In the Custom code settings section, select the Code Information tab and enter the include header directive and the source file path in the Include headers and Source files boxes, respectively.
Select the Additional source code tab and enter the function calls to the
initCapiFcn
andcleanCapiFcn
in the Initialize code and Terminate code boxes, respectively.Click OK.
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) set_param(capiMdl,CustomTerminator=addTerminateCode)
Add Step Function to Model Code Execution
One way to plug code into the model step function is by using a C Caller block. In the model canvas, add a C Caller block to the model and specify its function as realTimeCapiFcn
.
Alternatively, use the capiSigsParamsHelper
MATLAB® program to programmatically add the C Caller block.
capiSigsParamsHelper("cCaller")
The function realTimeCapiFcn
uses the C API interface to access the real-time values of model signals. Like the exploreCapiSignals
function described in the previous step, this function gets the pointer to the signal array map and gets the signal names. Then the function:
Gets the pointer to the real-time data address map. The pointer is a field of
rtwCAPI_ModelMappingInfo
, which is an inner structure in the main C API model map.Gets the data address indices from the signal map array.
Uses the indices to reference into the data address map to get the pointers to the real-time value of the signals.
Prints the signal names and their real-time values every 30th step of the model.
To view the definition of the function realTimeCapiFcn
, examine the file CapiSigsParams_04.c
.
/** realTimeCapiFcn ** * Uses the C API to send the signal values to the monitor. */ void realTimeCapiFcn() { if(capiStage == 2) { /* The C API data structures are already terminated. */ return; } int shouldPrint = !(capiStep%10); if(shouldPrint) { for(int idx=0 ; idx<sigCount ; idx++) { printf("step %0.3i: %s = %lf",capiStep, capiSigArr[idx].signalName, *((double*)sigPtrs[idx])); if(idx < sigCount-1) { printf(" , "); } } printf(".\n"); fflush(0); usleep(500000); } capiStep++; } /* End realTimeCapiFcn */
The figure shows the relationships of the data structures in the realTimeCapiFcn
function.
Add Mock Step Function to Model Simulation
In this example you do not simulate the model, but since you added the C Caller block you need to also specify header and source files also for the simulation. You cannot use the source file you specified for code generation, because it depends on the generated model code. Instead, for the simulation you specify the source file simMockSrc.c
. This file contains an empty definition of the realTimeCapiFcn
function. Use the mock header file, simMockSrc.h
, to specify the include header directive for the simulation.
Store the include header directive and the path to the mock file in a variables.
mockIncludeDirective = '# include "CapiSigsParamsFiles/simMockSrc.h"'; mockFilePath = "CapiSigsParamsFiles/simMockSrc.c";
To add the simulation custom code instructions:
Open the Configuration Parameters dialog box and navigate to the Simulation Target pane.
In the Code Information tab, paste the include header directive and the path to the source file in the Include headers and Source files boxes respectively.
Click OK.
Alternatively, you can specify these parameters programmatically by entering these commands in the Command Window:
set_param(capiMdl,SimCustomHeaderCode=mockIncludeDirective) set_param(capiMdl,SimUserSources=mockFilePath)
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, you configure the model to generate the C API elements also for model parameters, and you revise your external code to use the generate C API code to interact with both model signals and model parameters. To continue to the next step of the example, use this in the Command Window:
openExample("simulinkcoder/CapiSigsParams05Example")