%% Configure Data Interface in the Generated Code
% Specify signals, states, and parameters for inclusion in generated code. 
%
% Learn how to control these attributes of data 
% in the generated code:
%
% * Name
% * Data type 
% * Data storage class
%
% For information about the example model, see 
% <docid:ecoder_ug.example-rtwdemo_pcgd_stage_1_p1_script Generate C Code from a Control Algorithm for an Embedded System>.
%% Open Example Model
% <matlab:RTWDemos.pcgd_open_pcg_model(2,0); Open the example model, |rtwdemo_PCG_Eval_P2|>. 
open_system('rtwdemo_PCG_Eval_P2')
%% Data Declaration
% Most programming languages require that you declare data and functions
% before using them. The declaration specifies: 
% 
% * Scope: The region of the program that has access to the data
% * Duration: The period during which the data exist in memory
% * Data type: The amount of memory allocated for the data
% * Initialization: A value, a pointer to memory, or NULL
%
% The combination of scope and duration is the storage class. If you do not
% provide an initial value, most compilers assign a zero value or a null pointer.
%
% Supported data types include:
%
% * |double|: Double-precision floating point
% * |single|: Single-precision floating point
% * |int8|: Signed 8-bit integer
% * |uint8|: Unsigned 8-bit integer
% * |int16|: Signed 16-bit integer
% * |uint16|: Unsigned 16-bit integer
% * |int32|: Signed 32-bit integer
% * |uint32|: Unsigned 32-bit integer
% * Fixed Point: 8-, 16-, 32-bit word lengths
% 
% With storage classes you can:
% 
% * Generate exported files, with custom names, that contain global
% variable declarations and definitions.
% * Import custom header files that contain global variable declarations.
% * Generate |const| or |volatile| type qualifiers in declarations.
% * Represent a parameter as a macro (|#define| or compiler option).
% * Package signals or parameters into flat structures or bit fields.
%% Control Data in Simulink(R) and Stateflow(R)
% This example uses data objects to specify code generation settings for
% data. Alternatively, you can store the settings in the model by using dialog boxes.
% Both methods allow full control over the data type and storage
% class. You can use both methods in a single model.
%
% This example focuses on these types of data objects:
%
% * Signal
% * Parameter
% * Bus
%
% The code generator uses the objects from the MATLAB base workspace or a 
% Simulink data dictionary. You can create and inspect the objects with 
% commands at the command prompt
% or by using the Model Data Editor or the Model Explorer with the Code
% Mappings Editor.
%
% As an example, inspect the definition of the |Simulink.Signal| object
% |pos_cmd_one|, which the model created in the base workspace:
%
% # Open the *Embedded Coder* app.
% # On the *Modeling* tab, click *Model Data Editor*.
% # In the Model Data Editor, inspect the *Signals* tab.
% # Click the *Show/refresh additional information* button.
% # Next to the *Filter contents* box, toggle the *Filter using
% selection* button.
% # In the model, select the |pos_cmd_one| signal line. Now, the data table contains
% two rows: One that corresponds to the signal line in the model and one
% that corresponds to the signal object in the base workspace. For the row
% that corresponds to the signal line, the *Resolve* check box is selected,
% which means the signal line acquires settings from the signal object.
% # Optionally, to inspect other properties of the signal object, adjust the setting
% for the *Change view* drop-down list.
% # In the model, select the |pos_cmd_one| signal line and pause on the ellipsis 
% that appears above or below the signal line to open the action bar. Click
% the Add Signal button.
% # Open the *Code Mappings Editor*, click the *Signals* tab. Inspect
% the |pos_cmd_one| signal storage class.
%
% Return to the Model Data Editor, toggle the *Filter using selection button*.
% Now, the data table shows these signal lines and signal objects:
%
% * |pos_cmd_one|
% * |pos_rqst|
% * |P_InErrMap|
% * |ThrotComm|
% 
% |ThrotComm| is a bus signal, which is an instantiation of the |Simulink.Bus| 
% object |ThrottleCommands|. If a bus signal is nonvirtual,
% the signal appears as a structure in the C code. 
% Bus objects do not appear in
% the Model Data Editor. However, you can inspect the object in the Model Explorer
% (*View > Model Explorer*).
% 
% As in C, you can use a bus definition (|ThrottleCommands|) to create 
% multiple instances of the structure. In a model diagram, a bus signal 
% appears as a wide line with central dashes. 
%
% <<../BusObjectLine.png>>
%
% A data object has properties that you configure for simulation and for
% code generation, including:
%
% * |DataType| (numeric data type for storage in the generated code)
% * |StorageClass| (storage class for code generation)
% * |Value| (parameter value)
% * |InitialValue| (initial value for signal)
% * |Alias| (alternative name for the data, which the code generator uses)
% * |Dimensions| (size and number of dimensions of parameter or signal
% value)
% * |Complexity| (numeric complexity)
% * |Unit| (physical units such as cm)
% * |Min| (minimum value)
% * |Max| (maximum value)
%
% Use the property |Description| to specify custom documentation for data objects.
%% Add New Data Objects
% You can create data objects for named signals, states, and parameters.
% To associate a data object with a construct, the construct must have a
% name. 
%
% The Data Object Wizard tool finds constructs for which you
% can create data objects, and then creates the objects for you. The example 
% model includes two signals that are not associated with data objects:
% |fbk_1| and |pos_cmd_two|.
%
% To find the signals and create data objects for them:
%
% 1. Open the Data Object Wizard. 
%
%   dataobjectwizard('rtwdemo_PCG_Eval_P2')
%%
% 2. Click *Find* to find candidate constructs.
%
% <<../data_object_wiz.jpg>> 
%
% 3. Click *Select All* to select all candidates.
%
% 4. Click *Create* to create the data objects.
%
% The Data Object Wizard performs the equivalent of the following commands:
fbk_1 = Simulink.Signal;
fbk_1.Dimensions = 1;
fbk_1.DataType = 'double';
outport = get_param('rtwdemo_PCG_Eval_P2/fbk_1','PortHandles');
outport = outport.Outport;
set_param(outport,'MustResolveToSignalObject','on')

pos_cmd_two = Simulink.Signal;
pos_cmd_two.Dimensions = 1;
pos_cmd_two.DataType = 'double';
outport = get_param('rtwdemo_PCG_Eval_P2/PI_ctrl_2','PortHandles');
outport = outport.Outport;
set_param(outport,'MustResolveToSignalObject','on')
%% Configure Data Objects
% Set the data type and storage class for each data object.
% To configure data object properties, inspect the appropriate tab in the Model
% Data Editor. Use the *Change view* drop-down list to show design
% properties (such as data type) and code generation settings (such as
% storage class).
%
% In the Model Data Editor, inspect the *Signals* tab and click the
% *Show/refresh additional information* button to display information for the signal objects
% that the Data Object Wizard created.
% Then, configure these properties for the objects:
%
% * |fbk_1|: Data type |double|, storage class |ImportedExtern|
% * |pos_cmd_two|: Data type |double|, storage class |ExportedGlobal|
%
% Alternatively, you can use these commands at the command prompt to configure the objects:
fbk_1.DataType = 'double';
fbk_1.StorageClass = 'ImportedExtern';

pos_cmd_two.DataType = 'double';
pos_cmd_two.StorageClass = 'ExportedGlobal';
%% Control File Placement of Parameter Data
% With Embedded Coder(R), you can control the file placement of
% definitions for 
% parameters and constants. The example model writes the parameter definitions
% to the file |eval_data.c|.  
%
% To change the placement of parameter and constant definitions, set the
% data placement options for the model configuration. In the
% Configuration Parameters dialog box, configure the options on the
% *Code Generation > Code Placement* pane.  
%
% In the example model, inspect the *Code Placement* pane in the Configuration Parameters dialog
% box. The model places data definitions in the file
% |eval_data.c| and declarations in the file |eval_data.h|.
%% Declare Block Parameters Tunable or Inlined
% You can control the default tunability of block parameters in the generated
% code by setting model configuration parameter *Default
% parameter behavior*.
%
% For the example model, the default parameter behavior is set to |Inlined|. By
% default, block parameters appear in the code as numeric literal values,
% not as variables stored in memory. You can use |Simulink.Parameter| objects to
% override inlining and preserve tunability for individual
% parameters.
%% Enable Signal Data Objects in Generated Code
% Make sure that the signal data objects (|Simulink.Signal|) appear 
% in the generated code. For individual signal lines in the model, select the option *Signal
% name must resolve to Simulink signal object* to explicitly resolve the
% signal name to a |Simulink.Signal| object in a workspace or data
% dictionary. In the Model Data Editor, set *Change
% view* to |Code| and select the check box in the *Resolve* column.
%
% Alternatively, you can select the option for all signals in a model. At the 
% command prompt, use the |disableimplicitsignalresolution| function.
%% View Data Objects in Generated Code
% <matlab:RTWDemos.pcgd_buildDemo(2,0); Generate code from the example model>.
rtwbuild('rtwdemo_PCG_Eval_P2');
%%
% Create a code generation report to more easily view the generated files.
% In the Simulink Editor, select model configuration parameter *Open Model Report*. 
%
% You can access these generated files:
%
% * |rtwdemo_PCG_Eval_P2.c|: Defines the step and initialization functions. Uses the defined data objects.
% * |eval_data.c|: Assigns initial values to the defined parameters. The model
% configuration specifically sets the file name.
% * |eval_data.h|: Provides |extern| declarations of parameter data.
% The model configuration specifically sets the file name.
% * |ert_main.c|: Defines scheduling functions.
% * |rtwdemo_PCG_Eval_P2.h|: Contains the type definitions of the default
% structures that store 
% signal, state, and parameter data. Due to the data object settings, some data appear in |eval_data.c|
% instead.
% * |PCG_Eval_p2_private.h|: Declares private (local) data for the generated functions.
% * |rtwdemo_PCG_Eval_P2_types.h|: Declares the real-time model data structure.
% * |rtwtypes.h|: Provides mapping to the data types that Simulink(R) Coder(TM) defines (|typedef|). Used for integration with external systems.
%
% For example, view the file |eval_data.c|,
% which allocates |const| memory for global variables that correspond to
% the |Simulink.Parameter| objects in the base workspace.
cfile = fullfile('rtwdemo_PCG_Eval_P2_ert_rtw','eval_data.c');
rtwdemodbtype(cfile,'/* Exported data definition */','* [EOF]',1,1)
%%
% View the code algorithm in the model |step| function in the
% file |rtwdemo_PCG_Eval_P2.c|. The algorithm uses the data object names
% directly.
%
cfile = fullfile('rtwdemo_PCG_Eval_P2_ert_rtw','rtwdemo_PCG_Eval_P2.c');
rtwdemodbtype(cfile,'/* Model step function */',...
    '/* Sum: ''<S2>/Sum3'' incorporates:',1,0);
%%
% Without storage classes and other code generation settings that the data 
% objects specify, the generated code:
%
% * Inlines invariant signals and block parameters when you select these
% optimizations in the model configuration parameters
% * Places model input and output signals, block states, and tunable parameters in global
% data structures
% * Does not create global variables that correspond to MATLAB(R) variables
% 
% In contrast, the example code shows that most of the default data structures have been 
% replaced with user-defined data objects. For example, these signals
% and parameters appear as global variables in the code:
%
% * |pos_rqst|
% * |fbk_1|
% * |I_Gain|
% * |I_OutMap|
% * |I_InErrMap|
%
% However, the local variable |rtb_IntegralGainShape| and the 
% state variable |rtwdemo_PCG_Eval_P2_DWork.Discrete_Time_Integrator1_DSTAT|
% still use code generator data structures. Data objects do not
% exist for these entities.
%% Store Model Data in Data Dictionary
% When you end your MATLAB session, variables that you create in the base
% workspace do not persist. To permanently store data objects and bus
% objects, consider linking the model to a data dictionary.
%
% # In the example model, on the *Modeling* tab, under *Design*, click *Link to Data Dictionary*.
% # In the Model Properties dialog box, click *New*.
% # In the Create a New Data Dictionary dialog box, set *File name* to
% |rtwdemo_PCG_Eval_dict| and click *Save*. 
% # In the Model Properties dialog box, click *Apply*.
% # Click *Migrate data*.
% # Click *Migrate* in response to message about copying referenced variables.
% # Click *OK*.
%
% Alternatively, to manually migrate the objects into a data dictionary, you
% can use programmatic commands:

% Create a list of the variables and objects that the target
% model uses.
usedVars = {Simulink.findVars('rtwdemo_PCG_Eval_P2').Name};
% Create a new data dictionary in your current folder. Link the model to
% this new dictionary.
dictObj = Simulink.data.dictionary.create('rtwdemo_PCG_Eval_dict.sldd');
set_param('rtwdemo_PCG_Eval_P2','DataDictionary','rtwdemo_PCG_Eval_dict.sldd')
% Import only the target variables from the base workspace to the data
% dictionary.
importFromBaseWorkspace(dictObj,'clearWorkspaceVars',true,'varList',usedVars);
saveChanges(dictObj);
%%
% The data dictionary permanently stores the objects that the model
% uses. To view the contents of the dictionary, click the model data badge
% in the lower-left corner of the model, then click the *Data Dictionary*
% link. In the Model Explorer *Model Hierarchy* pane, select the *Design
% Data* node.
%
% The separation of data from the model provides these benefits:
%
% *One model, multiple data sets*
%
% * Use of different data types to change the targeted hardware (for example, for floating-point and fixed-point targets)
% * Use of different parameter values to change the behavior of the control algorithm (for example, for reusable components with different calibration values)
%
% *Multiple models, one data set*
%
% * Sharing of data between Simulink(R) models in a system
% * Sharing of data between projects (for example, transmission, engine, and wheel controllers might all use the same CAN message data set)
%
%   Copyright 2007-2019 The MathWorks, Inc.

