%% Design Data Interface by Configuring Inport and Outport Blocks
% 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. For more information, see
% <docid:ecoder_ug.btm45u7-1 Customize Generated C Function Interfaces>.
%% Design Data Interface
% Open the example model <matlab:rtwdemo_configrpinterface |rtwdemo_configrpinterface|>.
open_system('rtwdemo_configrpinterface')
%%
% Configure the model to show the generated names of blocks.
set_param('rtwdemo_configrpinterface','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.
%
% 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).
%% Configure Default Storage Class
% You can configure a default storage class for Inport blocks and Outport
% blocks then select the blocks that should use the specified default.
%
% # Open the *Simulink Coder* app.
% # In the C Code tab, select *Code Interface > Default Code Mappings*.
% # In the Code Mappings editor, under *Inports and Outports*, set the
% default storage class for both *Inports* and *Outports* to
% |ExportedGlobal|.
% # Next, on the *Inports* tab, select the data items that should
% use the default storage class. Press *Ctrl* and click each inport.
% # For the selected inports, set the storage class to |Model default: ExportedGlobal|.
% # Similarly, on the *Outports* tab, set the storage class for the outport to |Model default:
% ExportedGlobal|.
%
% Alternatively, to configure the data defaults at the command prompt, use these commands:
cm = coder.mapping.api.get('rtwdemo_configrpinterface');
setDataDefault(cm,'Inports','StorageClass','ExportedGlobal');
setDataDefault(cm,'Outports','StorageClass','ExportedGlobal');

setInport(cm,'In1','StorageClass','Model default');
setInport(cm,'In2','StorageClass','Model default');
setInport(cm,'In3','StorageClass','Model default');
setInport(cm,'In4','StorageClass','Model default');

setOutport(cm,'Out1','StorageClass','Model default','Identifier','output_sig');

%%
% Generate code from the model.
rtwbuild('rtwdemo_configrpinterface');
%%
% View the generated file |rtwdemo_configrpinterface.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_configrpinterface_grt_rtw','rtwdemo_configrpinterface.c');
rtwdemodbtype(file,'/* Data with Exported storage */','real_T output_sig;',1,1)
%%
% The generated algorithm in the model |step| function directly references these
% global variables to calculate and store the output signal value, |output_sig|.
%

%% Route Signal Data to Multiple Outputs
% Once you have configured the default storage classes for Inports and
% Outports, you can choose to override this default and set the storage
% class for some data elements individually. For example, 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, leave the storage class of the target signal
% line configured to |Auto| (the default). Optimizations can then eliminate
% the signal line from the generated code.
% # In the Code Mappings editor, on the *Outports* tab, apply the storage class |GetSet| to one Outport block and
% |ExportToFile| to the other Outport block.
% # In the Property Inspector, configure the properties associated with
% each applied storage class.
open_system('ex_route_sig')

%% Limitations
% 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.

%% 
% Copyright 2020 The MathWorks, Inc.