%% Access Structured Data Through a Pointer That External Code Defines
% This example shows how to generate code that uses global data that some
% handwritten code defines. In the handwritten code, a pointer variable
% points to one of three structure variables that contain parameter data. A
% handwritten function switches the pointer between the structures. The
% generated code accesses the parameter data by dereferencing the pointer
% variable. 
%% Explore External Code
% Open the example source file <matlab:edit('rtwdemo_importstruct_user.c')
% |rtwdemo_importstruct_user.c|>. The code defines a default data structure
% variable |ReferenceStruct| as constant (|const|) data and statically
% initializes each field. This structure represents the reference data set.
file = 'rtwdemo_importstruct_user.c';
rtwdemodbtype(file,'/* Constant default data structure (reference data set) */',...
    '/* Volatile data structures (working data sets) */',1,0)
%%
% The code defines two other structure variables, |WorkingStruct1| and
% |WorkingStruct2|, as volatile (|volatile|) data.
rtwdemodbtype(file,'/* Volatile data structures (working data sets) */',...
    'volatile DataStruct_type WorkingStruct2;',1,1)


%%
% The code defines a function that can initialize:
%
% * An inactive working structure from the active working structure.
% * Both working structures from the reference structure.
%
rtwdemodbtype(file,'/* Function to initialize','/* Function to switch',1,0)

%%
% The code defines |StructPointer|, which is a |const volatile| pointer to a structure.
% The code initializes the pointer to
% the address of |ReferenceStruct|.
rtwdemodbtype(file,'/* Define structure pointer.',...
    'const volatile DataStruct_type',1,1)

%%
% Finally, the code defines a function that can dynamically set |StructPointer| to point to either 
% |ReferenceStruct|, |WorkingStruct1|, or |WorkingStruct2|.
rtwdemodbtype(file,'/* Function to switch','EOF',1,0)

%%
% The example header file <matlab:edit('rtwdemo_importstruct_user.h')
% |rtwdemo_importstruct_user.h|> defines the enumeration |Dataset_T| and the structure type
% |Datastruct_type|. The file includes (|#include|) the built-in Simulink(R)
% Coder(TM) header file |rtwtypes.h|, which defines (|typedef|) Simulink Coder data types
% such as |int16_T|.
file = 'rtwdemo_importstruct_user.h';
rtwdemodbtype(file,'#include "rtwtypes.h"','} DataStruct_type;',1,1)

%%
% The file also declares the global variables
% and the functions.
%% Purpose of External Code
% The code is designed so that the source code of a control algorithm
% (whether generated or handwritten) can read data from
% |ReferenceStruct|, |WorkingStruct1|, or |WorkingStruct2| by dereferencing
% (|->|) |StructPointer|. The two working structures (|WorkingStruct1| and
% |WorkingStruct2|) are located in volatile memory and are intended to be
% changed during runtime by an external calibration tool. The calibration
% engineer does not change the active working structure. Instead, the
% engineer changes the parameter values in the inactive working structure
% and then activates it by switching working structures.
%
% If necessary for safety or in preparation for shutting down the application, the
% calibration tool can point |StructPointer| to |ReferenceStruct| instead.
% |ReferenceStruct| stores default parameter values that do not change
% during execution.
%% Explore Example Model
% Open the example model, <matlab:rtwdemo_importstruct
% |rtwdemo_importstruct|>.
open_system('rtwdemo_importstruct')
%%
% The model creates variables and objects in the base workspace. The
% Constant block and the Gain block use the |ECoderDemos.Parameter| objects
% |GAIN| and |OFFSET| to set the *Constant value* and *Gain* block parameters.
% |ECoderDemos| is an example custom package that defines two classes,
% |Parameter| and |Signal|, and some custom storage classes.
%
% On the *Modeling* tab, click *Model Data Editor*.
%
% In the Model Data Editor, inspect the *Parameters* tab.
%
% Set the *Change view* drop-down list to |Code|.
%
% Click the *Show/refresh additional information* button. 
%
% The Model Data Editor shows rows
% that correspond to the *Constant value* and *Gain* parameters of the
% blocks and rows
% that corresponds to |OFFSET| and |GAIN|, which set the parameter values. In the *Storage Class* column, |OFFSET|
% and |GAIN| use the custom storage class |StructPointer|, which the |ECoderDemos|
% package defines.
%
% Open the Custom Storage Class Designer and inspect
% the custom storage classes in the |ECoderDemos| package. At the command
% prompt, use this command:
%
%   cscdesigner('ECoderDemos')
%
% This example package defines multiple custom storage classes, including
% |StructPointer|. You cannot edit the definitions. However, you can
% create your own packages and custom storage classes later. For an example
% that shows how to create a package and a custom storage class, see
% <docid:ecoder_ug.buq4dqk-1>.
%
% Under *Custom storage class
% definitions*, click |StructPointer|. The settings for this custom storage class enable the generated code to
% interact with the pointer variable, |StructPointer|, from the external code.
% For example, the custom storage class uses these settings:
%
% * *Data scope* is set to |Imported| because the example external code
% defines (allocates memory for) |StructPointer|. With this setting, the
% code generator avoids generating unnecessary, duplicate definitions for
% the data items, such as the |ECoderDemos.Parameter| objects, that use
% the custom storage class.
% * *Data access* is set to |Pointer| because in the example external code,
% |StructPointer| is a pointer.
% * *Memory section* is set to |ConstVolatile| because the example external
% code defines |StructPointer| as constant, volatile data (|const
% volatile|).
% * *Type* is set to |FlatStructure| because in the example external code,
% |StructPointer| points to a structure. With this setting, the
% generated code treats each data item (|ECoderDemos.Parameter| object) as a field of a flat
% structure whose variable name and type name you can specify.
% * On the *Structure Attributes* tab, *Struct name* is set to
% |StructPointer|. For a |FlatStructure| custom storage class, *Struct
% name* specifies the name of the structure variable in the generated code.
% In this example, |StructPointer| is the name of the variable that the
% external code defines.
% * *Type name* is set to |DataStruct_type|, which is the name of the
% structure type that the example external code defines.
%
% In the model, in the *Configuration Parameters* dialog box, inspect the
% *Code Generation > Custom Code* pane. 
%
% Under *Insert custom C code in generated*, select *Initialize function*.
% This parameter value specifies the code to include in the generated model
% initialize function. In this model, the configuration parameter is set so
% that the generated code calls the |InitInactiveWorkingStructs| function.
% |InitInactiveWorkingStructs| initializes the working structures with the
% values from |ReferenceStruct|. The initialization code then sets the
% pointer to the first working structure.
%
% Under *Additional build information*, select *Source files*. This
% configuration parameter identifies the example external code file
% |rtwdemo_importstruct_user.c| for inclusion in the build process after code generation.
%% Generate and Inspect Code
% Generate code from the model.

%{
evalc('rtwbuild(''rtwdemo_importstruct'')');
%}
%%
% In the generated file |rtwdemo_importstruct.c|, the model
% initialization function calls |InitInactiveWorkingStructs|.
file = fullfile('rtwdemo_importstruct_ert_rtw','rtwdemo_importstruct.c');
rtwdemodbtype(file,'/* Model initialize function */','* File trailer for generated code.',1,0)
%%
% The algorithm in the model execution (|step|) function dereferences the
% pointer variable
% |StructPointer|.
rtwdemodbtype(file,'/* Model step function */','/* Model initialize function */',1,0)
% Copyright 2019 The MathWorks, Inc.