%% Access Signal, State, and Parameter Data During Execution
% As you iteratively develop a model, you capture output signal and
% state data that model execution generates. You also
% tune parameter values during execution to observe results on the outputs. You can then base 
% your design decisions upon analysis of these outputs. To access this signal, state, and
% parameter data in a rapid prototyping environment, you can configure the generated code to store the data in
% addressable memory.    
%
% By default, optimization settings make the generated code more efficient
% by eliminating unnecessary signal storage and inlining the numeric values of
% block parameters. To generate code that instead allocates addressable memory
% for this data, you can disable the optimizations or specify code
% generation settings for individual data items. 
%% Explore Example Model
% Run a script that prepares the model |rtwdemo_basicsc| for this example.
run(fullfile(matlabroot,'examples','simulinkcoder','main','prepare_rtwdemo_basicsc'));
%%
% This data is configured for code generation:
%
% * Parameters |UPPER|, |LOWER|, |LIMIT|, |K1|, and |K2| (Stateflow),
% |T1Break|, |T1Data|, |T2Break|, |T2 Data|
% * Signals |Input1|, |Input2|, |Input3|, |Input4|, and |output|
% * States |X| (delay) and |mode| (data store memory write and Stateflow)
%%
% Open the example model, <matlab:rtwdemo_basicsc |rtwdemo_basicsc|>.
rtwdemo_basicsc
%%
% The model loads numeric MATLAB variables into the base
% workspace. The workspace variables set some block parameters in the model.
% However, The Gain block in the model uses the literal value |2|.
%% Disable Optimizations
% 1. In the model, clear the model configuration parameter *Signal
% storage reuse*. When you clear this optimization and other optimizations such as
% *Eliminate superfluous local variables (expression folding)*, the
% generated code allocates memory for signal lines. Clearing
% *Signal storage reuse* disables most of the other optimizations.
set_param('rtwdemo_basicsc','OptimizeBlockIOStorage','off')
%%
% 2. Set the model configuration parameter *Default parameter behavior* to |Tunable|. When set to |Tunable|, this
% configuration parameter causes the generated code to
% allocate memory for block parameters and workspace variables.
set_param('rtwdemo_basicsc','DefaultParameterBehavior','Tunable')
%%
% 3. Generate code.
rtwbuild('rtwdemo_basicsc')
%%
% 4. In the code generation report, view the file |rtwdemo_basicsc.h|. This
% header file defines a structure type that contains signal data. The
% structure contains fields that each represent a signal line in the model.
% For example, the output signal of the Gain block, whose name is |Gain|, appears as the field |Gain|.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T;',1,1)
%%
% The file defines a structure type that contains block parameter data. For example, the
% *Gain* parameter of the Gain block appears as the field |Gain_Gain|. The other
% fields of the structure represent other block parameters and workspace
% variables from the model, including initial conditions for signals and states.
rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
%%
% 5. View the file |rtwdemo_basicsc_data.c|. This source file allocates global memory
% for a parameter structure and initializes the field values based on the
% parameter values in the model.
%%
% 6. View the source file |rtwdemo_basicsc.c|.
% The code allocates global memory for a structure variable that
% contains signal data.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.c');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T rtwdemo_basicsc_B;',1,1)
%%
% The code algorithm in the model |step| function calculates the signal
% values. It then assigns these values to the fields of the signal structure. To
% perform the calculations, the algorithm uses the parameter values from
% the fields of the parameter structure.
%% Exclude Data Items from Optimizations
% When you want to select code generation optimizations such as *Signal storage reuse*,
% you can preserve individual data items from the optimizations. The generated
% code then allocates addressable memory for the items.
%
% Select the optimizations that you previously cleared.
set_param('rtwdemo_basicsc','OptimizeBlockIOStorage','on')
set_param('rtwdemo_basicsc','LocalBlockOutputs','on')
set_param('rtwdemo_basicsc','DefaultParameterBehavior','Inlined')
%%
% 1. On the *Modeling* tab, click *Model Data Editor*.
%
% 2. In the Model Data Editor, inspect the *Signals* tab.
%
% 3. Set the *Change view* drop-down list to |Instrumentation|.
%
% 4. In the model, select the output signal of the Gain block.
%
% 5. In the Model Data Editor, select the check box in the *Test Point*
% column.
portHandle = get_param('rtwdemo_basicsc/Gain','PortHandles');
portHandle = portHandle.Outport;
set_param(portHandle,'TestPoint','on')
%%
% 6. Inspect the *Parameters* tab.
%
% 7. In the model, select the Gain block.
%
% 8. In the Model Data Editor, use the *Value* column to set the gain value to
% |K1|.
%
% 10. Next to |K1|, click the action button (with three vertical dots) and
% select *Create*.
%
% 11. In the Create New Data dialog box, set *Value* to
% |Simulink.Parameter(2)| and click *Create*. A |Simulink.Parameter| object
% named |K1|, with value |2|, appears in the base workspace.
%
% 12. In the property dialog box for |K1|, apply a storage class other than
% |Auto| by using *Storage class*. For example, use the storage class
% |Model default| to represent the parameter object as a field of the
% global parameters structure.
set_param('rtwdemo_basicsc/Gain','Gain','K1');
K1 = Simulink.Parameter(2);
K1.StorageClass = 'Model default';
%%
% 13. Generate code.
rtwbuild('rtwdemo_basicsc')
%%
% 14. In the code generation report, view the file |rtwdemo_basicsc.h|. The
% structure that contains signal data now defines only one field, |Gain|,
% which represents the test-pointed output of the Gain block.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T;',1,1)
%%
% The structure that contains block parameter data defines one field, |K1|,
% which represents the parameter object |K1|.
rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
%% Access Data Through Generated Interfaces
% You can configure the generated code to contain extra code and files so
% that you can access model data through standardized interfaces. For example,
% use the C API to log signal data and tune parameters during execution.
%
% `. Copy this custom source code into a file named |ex_myHandCode.c| in your current
% folder.
%
% <include>ex_myHandCode.c</include>
%
% 2. Copy this custom header code into a file named |ex_myHandHdr.h| in your
% current folder.
%
% <include>ex_myHandHdr.h</include>
%
% These files use the C API to access signal and parameter data in the code
% that you generate from the example model.
%
% 3. Set model configuration parameters *Header file* and *Source files* to 
% |#include "ex_myHandHdr.h"| and |ex_myHandCode.c|, respectively.
set_param('rtwdemo_basicsc','CustomHeaderCode','#include "ex_myHandHdr.h"')
set_param('rtwdemo_basicsc','CustomSource','ex_myHandCode.c')
%%
% 4. Select model configuration parameter *MAT-file Logging*. The generated executable runs only until the
% simulation stop time (which you set in the model configuration
% parameters).
set_param('rtwdemo_basicsc','MatFileLogging','on')
%%
% 5 Select C API model configuration parameters *parameters*, *signals*, *states*, and *root-level I/O*.
set_param('rtwdemo_basicsc','RTWCAPIParams','on')
set_param('rtwdemo_basicsc','RTWCAPISignals','on')
set_param('rtwdemo_basicsc','RTWCAPIStates','on')
set_param('rtwdemo_basicsc','RTWCAPIRootIO','on')
%%
% 5. Load the Custom Code block library.
custcode
%%
% 6. Add a System Outputs block to the model.
add_block('custcode/System Outputs','rtwdemo_basicsc/System Outputs')
%%
% 7. In the System Outputs block dialog box, set *System Outputs Function
% Execution Code* to this code:
%
%  {
%  rtwdemo_basicsc_U.input2++;
%  rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
%  tuneFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
%  }
%
% 8. In the block dialog box, set *System Outputs Function Exit Code* to this code:
%
%  {
%  rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
%  logFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
%  }
%
% Alternatively, to configure the System Outputs block, at the command prompt, use these commands:
temp.TLCFile = 'custcode';
temp.Location = 'System Outputs Function';
temp.Middle = sprintf(['{\nrtwdemo_basicsc_U.input2++;'...
    '\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);'...
    '\ntuneFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));\n}']);
temp.Bottom = sprintf(['{\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);'...
    '\nlogFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));\n}']);
set_param('rtwdemo_basicsc/System Outputs','RTWdata',temp)
%%
% 9. Generate code.
rtwbuild('rtwdemo_basicsc')
%%
% 10. In the code generation report, view the interface file
% |rtwdemo_basicsc_capi.c|. This file initializes the arrays of structures
% that you can use
% to interact with data items through the C API. For example, in the array of structures |rtBlockSignals|, the first
% structure (index 0) describes
% the test-pointed output signal of the Gain block in the model.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc_capi.c');
rtwdemodbtype(file,'/* Block output signal information */',...
    '/* Individual block tuning',1,0)
%%
% The fields
% of the structure, such as |addrMapIndex|, indicate indices into other
% arrays of structures, such as |rtDataAddrMap|, that describe the
% characteristics of the signal. These characteristics include the address
% of the signal data (a pointer to the data), the numeric data type, and the dimensions of the signal.
%
% 11. In the file |rtwdemo_basicsc.c|, view
% the code algorithm in the model |step| function. The algorithm first
% executes the code that you specified in the System Outputs block.
file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.c');
rtwdemodbtype(file,'/* user code (Output function Body) */',...
    '/* Logic: ''<Root>/LogOp'' incorporates:',1,0)
%%
% This code first perturbs the input signal |input2| by incrementing
% the value of the signal each time the |step| function executes. The code
% then uses the built-in macro |rtmGetDataMapInfo| to extract model mapping
% information from the model data structure |rtwdemo_basicsc_M|. The
% pointer |MMI| points to the extracted mapping information, which allows the
% functions |tuneFcn| and |logFcn| to access the information contained in the arrays of
% structures that the C API file |rtwdemo_basicsc_capi.c| defines.
%
% 12. View the function |tuneFcn| in the file |ex_myHandCode.c|. This
% function uses the C API (through the model mapping information |mmi|) and
% a pointer to the simulation time to print the value of the parameter |K1|
% at specific times during code execution. When the simulation time
% reaches 5 seconds, the function changes the parameter value in memory. By
% using a |switch case| block, the function can access the parameter data
% whether the data type is |int8| or |double|.
%
% 13. View the code algorithm in the model |step| function again. Near the end
% of the function, the algorithm executes the code that you
% specified in the System Outputs block. This code calls the
% function |logFcn|.
rtwdemodbtype(file,'/* user code (Output function Trailer) */',...
    '/* Matfile logging */',1,0)
%%
% 14. View the function |logFcn| in the file |ex_myHandCode.c|. The
% function uses the C API to print the value of the test-pointed signal.
% The function can access the signal data whether the data
% type is |single| or |double|.
%
% 15. At the command prompt, run the generated executable
% |rtwdemo_bascisc.exe|.
%
%   system('rtwdemo_basicsc')
%
% The parameter and signal values appear in the Command Window output. 
%
% For more information about data interfaces, including the C API, see
% <docid:rtw_doccenter.bu38el2-1 Data Exchange Interfaces>.


%% 
% Copyright 2012 The MathWorks, Inc.