The data interface of a model is the means by which the model exchanges data (for example, signal values) with other, external models or systems. Customize the data interface of a model to:
Enable integration of the generated code with your own code.
Improve traceability and readability of the code.
At the top level of a model, Inport and Outport blocks represent the input and output signals of the model. To customize the data interface in the generated code, configure these blocks. Early in the design process, when a model can contain unconnected Inport and Outport blocks, use this technique to specify the interface before developing the internal algorithm.
When you apply storage classes to Inport and Outport blocks, each block appears in the generated code as a field of a global structure or as a separate global variable that the generated algorithm references directly. If you have Embedded Coder, you can use function prototype control instead of storage classes to pass data into and out of the model step
function as formal parameters. See Customize Generated C Function Interfaces (Embedded Coder).
Open the example model rtwdemo_basicsc
.
open_system('rtwdemo_basicsc')
Configure the model to show the generated names of blocks.
set_param('rtwdemo_basicsc','HideAutomaticNames','off')
On the Modeling tab, click Model Data Editor.
In the Model Data Editor, select the Inports/Outports tab. Each row in the table represents an Outport block or a signal that exits an Inport block.
Name the signal data that the Outport block Out1
represents. Set Signal Name to output_sig
.
For each of the signals that exit the Inport blocks, set Data Type to single
or to a different data type. Due to the data type inheritance settings that the other blocks in the model use by default, downstream signals in the rest of the model use the same or a similar data type.
Optionally, configure other design attributes such as Min and Max (minimum and maximum values).
Set the Change View drop-down list to Code
.
For the Outport block and Inport blocks, set Storage Class to ExportedGlobal
. To configure the blocks in one step, select the rows in the table.
To configure the blocks and signals, you can use these commands at the command prompt.
portHandles = get_param('rtwdemo_basicsc/In1','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','ExportedGlobal'); portHandles = get_param('rtwdemo_basicsc/In2','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','ExportedGlobal'); portHandles = get_param('rtwdemo_basicsc/In3','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','ExportedGlobal'); portHandles = get_param('rtwdemo_basicsc/In4','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','ExportedGlobal'); set_param('rtwdemo_basicsc/Out1','SignalName','output_sig',... 'StorageClass','ExportedGlobal')
Generate code from the model.
rtwbuild('rtwdemo_basicsc');
### Starting build procedure for: rtwdemo_basicsc ### Successful completion of build procedure for: rtwdemo_basicsc
View the generated file rtwdemo_basicsc.c
. Because you applied the storage class ExportedGlobal
to the Inport and Outport blocks, the code creates separate global variables that represent the inputs and the output.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.c'); rtwdemodbtype(file,'/* Exported block signals */','real32_T output_sig;',1,1)
/* Exported block signals */ real32_T input1; /* '<Root>/In1' */ real32_T input2; /* '<Root>/In2' */ real32_T input3; /* '<Root>/In3' */ real32_T input4; /* '<Root>/In4' */ real32_T output_sig; /* '<Root>/Out1' */
The generated algorithm in the model step
function directly references these global variables to calculate and store the output signal value, output_sig
.
While you use the Model Data Editor to configure the interface of a system, consider using the interface display to view the system inputs and outputs (Inport and Outport blocks) at a high level. See Configure Data Interface for Component (Simulink).
If you have Embedded Coder, you can configure a default storage class for Inport blocks and Outport blocks. As you add such blocks to the model, they acquire the storage class that you specify.
In the model, set Configuration Parameters > Code Generation > System target file to ert.tlc
.
In the Apps gallery, click Embedded Coder.
Underneath the block diagram, under Code Mappings > Data Defaults, for the Inports and Outports rows, set Storage Class to ExportedGlobal
.
Underneath the block diagram, open the Model Data Editor by clicking the Model Data Editor tab.
Use the Model Data Editor to set the storage class of the Inport and Outport blocks to Auto
. With this setting, the blocks acquire the default storage classes that you specified in Code Mappings > Data Defaults.
With Auto
, the global variables that correspond to the Inport and Outport blocks are subject to a naming rule that you specify in the model configuration parameters. By default, the naming rule adds the name of the model to the name of each variable. To remove the model name, change the value of Configuration Parameters > Code Generation > Identifiers > Global variables from $R$N$M
to $N$M
. The token $R
represents the model name.
Alternatively, to configure the data defaults and the configuration parameter, at the command prompt, use these commands:
set_param('rtwdemo_basicsc','SystemTargetFile','ert.tlc') coder.mapping.create('rtwdemo_basicsc') coder.mapping.defaults.set('rtwdemo_basicsc','Inports',... 'StorageClass','ExportedGlobal') coder.mapping.defaults.set('rtwdemo_basicsc','Outports',... 'StorageClass','ExportedGlobal') portHandles = get_param('rtwdemo_basicsc/In1','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','Auto'); portHandles = get_param('rtwdemo_basicsc/In2','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','Auto'); portHandles = get_param('rtwdemo_basicsc/In3','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','Auto'); portHandles = get_param('rtwdemo_basicsc/In4','portHandles'); outPortHandle = portHandles.Outport; set_param(outPortHandle,'StorageClass','Auto'); set_param('rtwdemo_basicsc/Out1','SignalName','output_sig',... 'StorageClass','Auto') set_param('rtwdemo_basicsc','CustomSymbolStrGlobalVar','$N$M')
You can route a single signal to multiple Outport blocks and apply a different storage class to each Outport. For example, use this technique to send signal data to a custom function (such as a device driver) and to a global variable that your custom algorithmic code can use:
Branch the target signal line to each Outport block.
For more efficient code, set the storage class of the target signal line to Auto
(the default). Optimizations can then eliminate the signal line from the generated code.
Use the Model Data Editor to apply the storage class GetSet
to one Outport block and ExportToFile
to the other Outport block. Apply a signal name to each block.
open_system('ex_route_sig')
You cannot apply a storage class to an Outport block if the input to the block has a variable size. Instead, apply the storage class to the signal line.