%% Data Interfaces in the Generated Code
% This example shows how the generated code exchanges data with an
% environment. 
%% Explore Example Model
% Open the example model |rtwdemo_roll|.
open_system('rtwdemo_roll')
%%
% At the root level, the model has a number of Inport blocks and one Outport block.
%
% In the model, set *Configuration Parameters > Code Generation > System
% target file* to |grt.tlc|. 
set_param('rtwdemo_roll','SystemTargetFile','grt.tlc')
%%
% Inspect the setting for *Configuration Parameters > Code Generation >
% Interface > Code interface packaging*. The setting |Nonreusable function|
% means that the generated code is not reusable (not reentrant).
%
% For this example, to generate simpler code, clear the *Configuration
% Parameters > Code Generation > Interface > Advanced parameters > Mat-file
% logging*.
set_param('rtwdemo_roll','MatFileLogging','off')
%% Generate Nonreusable Code
% Generate code from the model.
rtwbuild('rtwdemo_roll')
%%
% Inspect the file |rtwdemo_roll.h|. The file defines a structure type that
% represents input data and a type that represents output data.
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,...
    '/* External inputs (root inport signals with default storage) */',...
    '} ExtY_rtwdemo_roll_T;',1,1)
%%
% Each field corresponds to an Inport or Outport block at the root level of the
% model. The name of each field derives from the name of the block.
%
% The file also defines a structure type, the _real-time model data
% structure_, whose single field stores a run-time indication of whether the
% generated code has encountered an error during execution. 
rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
    '/* Block states (default storage) */',1,0)
%%
% When you modify model configuration
% parameters to suit your application, this structure can also contain
% other data that pertain to the entire model, such as scheduling information.
%
% For the structure type that represents the real-time model data
% structure, the file |rtwdemo_roll_types.h| creates an alias (|typedef|) that the
% generated code later uses to allocate memory for the structure.
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll_types.h');
rtwdemodbtype(file,'/* Forward declaration for rtModel */',...
    'RT_MODEL_rtwdemo_roll_T;',1,1)
%%
% Using these structure types, the file |rtwdemo_roll.c| defines (allocates memory for) global structure
% variables that store input and output data for the generated algorithm.
% The file also defines variables that represent the real-time model data
% structure and a pointer to the structure.
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,...
    '/* External inputs (root inport signals with default storage) */',...
    '= &rtwdemo_roll_M_;',1,1)
%%
% The file |rtwdemo_roll.h| declares these structure variables. Your external code can
% include (|#include|) this file, whose general name is |_model_.h| where |_model_| is the name of the model, to
% access data that participate in the model interface.
% 
% In |rtwdemo_roll.c|, the model |step| function, which represents the primary model algorithm,
% uses a |void| |void| interface (without arguments).
rtwdemodbtype(file,...
    '/* Model step function */','void rtwdemo_roll_step(void)',1,1)
%%
% In the function definition, the algorithm reads input data and writes output
% data by directly accessing the global structure variables. For example,
% near the end of the algorithm, the code for the |EngSwitch| block
% reads the value of the |AP_Eng| field (which represents an input) and,
% based on that value, conditionally writes a constant value to the
% |Ail_Cmd| field (which represents an output).
rtwdemodbtype(file,'if (rtwdemo_roll_U.AP_Eng) {','      }',1,1)
%%
% Due to the |void| |void| interface and the direct data access, the
% function is not reentrant. If you call the function multiple times in an
% application, each call reads and writes input and output data to the same global structure variables,
% resulting in data corruption and unintentional interaction between the
% calls.
%
% The model initialization function, |rtwdemo_roll_initialize|, initializes
% input and output data to zero. The function also initializes the error
% status. The function directly accesses the global variables, which means the function is not reentrant.
rtwdemodbtype(file,'/* Model initialize function */',...
    'rtmSetErrorStatus(rtwdemo_roll_M, (NULL));',1,1)
%%
rtwdemodbtype(file,'  /* external inputs */',...
    '/* SystemInitialize for Atomic SubSystem:',1,0)
%% Generate Reusable Code
% You can configure the generated code as reentrant, which means that you can
% call the entry-point functions multiple times in an application. 
% With this configuration, instead of directly accessing
% global variables, the entry-point functions exchange input, output, and
% other model data through formal parameters (pointer arguments). 
% With these pointer arguments, each call can read inputs and write outputs
% to a set of separate global variables, preventing unintentional interaction between the
% calls.
%
% In the model, set *Configuration Parameters > Code Generation >
% Interface > Code interface packaging* to |Reusable function|.
set_param('rtwdemo_roll','CodeInterfacePackaging','Reusable function')
%%
% Generate code from the model.
rtwbuild('rtwdemo_roll')
%%
% Now, in |rtwdemo_roll.h|, the real-time model data structure contains pointers to 
% the error indication, the input data, the output data, and additional data in
% the form of a |DWork| substructure (which stores, for example, block states
% such as the state of a Discrete-Time Integrator block).
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');
rtwdemodbtype(file,'/* Real-time Model Data Structure */',...
    '/* External data declarations for dependent source files */',1,0)
%%
% To call the generated code multiple times in an application, your code
% must allocate memory for a real-time model data structure per call. 
% The file |rtwdemo_roll.c| defines a specialized function that allocates
% memory for a new real-time model data structure and returns a pointer to the structure. 
% The function also allocates memory for 
% the substructures 
% that the fields in the model data structure point to, such as the input and output structures.
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Model data allocation function */',...
    'RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)',1,1)
%%
% In |rtwdemo_roll.c|, the model |step| function accepts an argument that
% represents the real-time model data structure.
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,...
    '/* Model step function */','void rtwdemo_roll_step',1,1)
%%
% In the function definition, the algorithm first extracts each pointer from 
% the real-time model data structure into a local variable.
rtwdemodbtype(file,...
    '*rtwdemo_roll_DW =','rtwdemo_roll_M->outputs;',1,1)
%%
% Then, to access the
% input and output data stored in global memory, the algorithm interacts with these local variables.
rtwdemodbtype(file,'  if (rtwdemo_roll_U->AP_Eng) {',...
    '  /* End of Switch: ''<Root>/EngSwitch'' */',1,1)
%%
% Similarly, the model initialization function accepts the real-time model
% data structure as an argument.
rtwdemodbtype(file,...
    '/* Model initialize function */','void rtwdemo_roll_initialize',1,1)
%%
% Because each call that you make to an entry-point function interacts with a separate
% real-time model data structure, you avoid unintentional interaction
% between the calls.

%% 
% Copyright 2012 The MathWorks, Inc.