%% Insert Pragmas by Using Memory Sections
% % NOTE: As of 18a, this example is authored in XML (Greg S-T).
% %
% % In this example, you configure the default memory placement for all of the data
% % and functions of the algorithm represented by the example model
% % |rtwdemo_roll|. Then, for some parameter data, you override the default
% % placement. 
% %% Explore Example Model and Inspect Default Generated Code
% % Open the example model.
% %
% %   open_system('rtwdemo_roll')
open_system('rtwdemo_roll')
% %%
% % The model is configured to generate efficient production code. For
% % example, the configuration parameter *Default parameter behavior* is set
% % to |Inlined|.
% % 
% % Generate code from the model.
% evalc('rtwbuild(''rtwdemo_roll'')');
% %%
% % The file |rtwdemo_roll.h| defines structure types that represent data that the algorithm needs. For example, 
% % the file defines a structure type that represents block states such as the states of Discrete-Time Integrator
% % blocks.
% file = fullfile('rtwdemo_roll_ert_rtw','rtwdemo_roll.h');
% rtwdemodbtype(file,'/* Block states (default storage)','DW_rtwdemo_roll_T;',1,1)
% %%
% % The file also declares entry-point functions for the model.
% rtwdemodbtype(file,'/* Model entry point functions */','extern void rtwdemo_roll_terminate(void);',1,1)
% %%
% % The file |rtwdemo_roll.c| defines global structure variables to store the data and defines the functions. 
% %
% % In this example, assume your linker configuration file defines named
% % sections |MYALGORITHM_DATA| and |MYALGORITHM_CODE| in a |SECTIONS| directive. You can configure the
% % model so that the generated code includes pragmas, placing the memory allocated for the data and
% % functions in these named sections. 
% %
% % In this example, for a global variable named |myVar|, the pragma syntax is:
% %
% % |#pragma SEC_MYALGORITHM_DATA("myVar")|
% %
% % |double myVar;|
% %
% % For a function named |myFunction|, the pragma syntax is the same except for the section name:
% %
% % |#pragma SEC_MYALGORITHM_CODE("myFunction")|
% %
% % |void myFunction(void)|
% %% Create Memory Sections
% % In this example, you use two pragmas with different syntaxes, so you must
% % create two memory sections.
% %
% % In your current folder, create a folder named |+myPackage|. The folder
% % defines a package named |myPackage|. Later, the package contains the
% % definitions of the memory sections.
% %
% % To make the
% % package available outside of your current folder, you can
% % add the folder containing the |+myPackage| folder to the MATLAB path.
% %
% % Open the Custom Storage Class designer.
% %
% %   cscdesigner('myPackage');
% %
% % In the Custom Storage Class Designer, select the *Memory Section* tab.
% %
% % Click *New*.
% %
% % For the new memory section, set these options:
% %
% % * *Name* to |MYALGORITHM_DATA|.
% % * *Pragma surrounds* to |Each variable|.
% % * *Pre-memory-section pragma* to |#pragma
% % SEC_MYALGORITHM_DATA("%<identifier>")|.
% %
% % Click *Apply* and *Save*.
% %
% % Create another, similar memory section that corresponds to |MYALGORITHM_CODE|.
% %% Configure Default Pragmas for Data and Functions
% % In the model, select *Configuration Parameters > Code Generation >
% % Memory Sections*.
% %
% % Click *Refresh package list* and set *Package* to |myPackage|.
% %
% % Under *Memory sections for model functions and subsystem defaults*, set
% % all of the options to |MYALGORITHM_CODE|. Similarly, under *Memory
% % sections for model data and subsystem defaults*, set all of the options
% % to |MYALGORITHM_DATA|. For the example model, the generated code currently does not allocate memory for constant or
% % tunable parameters, but configuring all of the memory section
% % settings at once helps prevent memory section misses in the future.
% %
% % In your current folder, delete the existing |slprj| folder.
% %
% % Configure the model to generate only code. Select the configuration
% % parameter *Configuration Parameters > Generate code only*.
% set_param('rtwdemo_roll','GenCodeOnly','on')
% %%
% % Generate code from the model.
% rmdir slprj s
% mkdir('+myPackage')
% cd('+myPackage')
% mkdir('@Parameter')
% copyfile(fullfile('..','Parameter_supp.m'),fullfile('@Parameter','Parameter.m'))
% copyfile(fullfile('..','csc_reg_mem_sec_supp.m'),fullfile('csc_registration.m'))
% cd('..')
% set_param('rtwdemo_roll','MemSecPackage','myPackage')
% set_param('rtwdemo_roll','MemSecFuncInitTerm','MYALGORITHM_CODE')
% set_param('rtwdemo_roll','MemSecFuncExecute','MYALGORITHM_CODE')
% set_param('rtwdemo_roll','MemSecFuncSharedUtil','MYALGORITHM_CODE')
% 
% set_param('rtwdemo_roll','MemSecDataConstants','MYALGORITHM_DATA')
% set_param('rtwdemo_roll','MemSecDataIO','MYALGORITHM_DATA')
% set_param('rtwdemo_roll','MemSecDataInternal','MYALGORITHM_DATA')
% set_param('rtwdemo_roll','MemSecDataParameters','MYALGORITHM_DATA')
% evalc('rtwbuild(''rtwdemo_roll'')');
% %%
% % Now, the |rtwdemo_roll.c| file applies the pragmas to the definitions of
% % the structure variables and the functions. For each category of data and
% % functions that you configured in the model configuration parameters, the
% % code applies a pragma. For example, the code applies the
% % |MYALGORITHM_DATA| pragma to each of the structures that store block states,
% % root-level inputs, and root-level outputs.
% file = fullfile('rtwdemo_roll_ert_rtw','rtwdemo_roll.c');
% rtwdemodbtype(file,'/* Block states (default storage) */','/* Real-time model */',1,0)
% %% Apply Memory Section After Applying a Storage Class
% % To override optimizations that eliminate data items such as signals,
% % parameters, and states, you can apply a storage class to a data item.
% % You can also use a storage class to control the appearance of a data item
% % that optimizations cannot eliminate. However, any storage class other than
% % |SimulinkGlobal| removes the data item from the default data structures,
% % which means the memory sections that you configure in the model
% % configuration parameters do not apply to the data item any more.
% %
% % However, you can create your own custom storage class and associate a
% % memory section with it. Then, you can apply the storage class to a data
% % item, which implicitly applies the memory section, too.
% %
% % In |rtwdemo_roll|, in the |RollAngleReference| subsystem, the two
% % Constant blocks labeled |UpThr| and |LoThr| represent parameters of the
% % algorithm. Configure these parameters so that the generated code
% % allocates memory for them and places the memory in the |MYALGORITHM_DATA|
% % section.
% %
% % In the |myPackage| package folder, create a folder named |@Parameter|.
% % 
% % In the |@Parameter| folder, create a file named |Parameter.m|.
% %
% % <include>Parameter_supp.m</include>
% %
% % The file defines a class named |myPackage.Parameter|, which is derived from |Simulink.Parameter|. The class definition overrides the |setupCoderInfo| method, which the
% % |Simulink.Parameter| class already implements. The new implementation
% % specifies that objects of the |myPackage.Parameter| class use custom storage
% % classes from the |myPackage| package instead of custom storage classes from the |Simulink| package.
% %
% % Set your current folder to the folder that contains the |+myPackage|
% % folder.
% %
% % In the Custom Storage Class Designer for |myPackage|, select the *Custom
% % Storage Class* tab.
% %
% % Click *New*.
% %
% % For the new custom storage class, set these properties:
% %
% % * *Name* to |myCSC|.
% % * *Memory section* to |MYALGORITHM_DATA|.
% %
% % Click *Apply* and *Save*.
% %
% % In the model, navigate into the |RollAngleReference| subsystem and select *View > Model Data Editor*.
% %
% % In the Model Data Editor, select the *Parameters* tab.
% %
% % In the model, click the Constant block labeled |UpThr|.
% %
% % Use the *Value* column to set the constant value to |UpThrParam|.
% %
% % Next to |UpThrParam|, click the action button (with three vertical dots)
% % and select *Create*.
% %
% % In the Create New Data dialog box, set *Value* to |myPackage.Parameter(6)|
% % and click *Create*. The |myPackage.Parameter| object appears in the base
% % workspace.
% %
% % In the property dialog box for |UpThrParam|, set *Storage class* to
% % |myCSC|. Click *OK*.
% %
% % Use the Model Data Editor to set the value of the |LoThr| block by using
% % a |myPackage.Parameter| object named |LoThrParam|. Instead of |6|, use
% % the object to store the value |-6|.
% %
% % Generate code from the model.
% LoThrParam = myPackage.Parameter(-6);
% UpThrParam = myPackage.Parameter(6);
% LoThrParam.CoderInfo.StorageClass = 'Custom';
% LoThrParam.CoderInfo.CustomStorageClass = 'myCSC';
% UpThrParam.CoderInfo.StorageClass = 'Custom';
% UpThrParam.CoderInfo.CustomStorageClass = 'myCSC';
% set_param('rtwdemo_roll/RollAngleReference/UpThr','Value','UpThrParam')
% set_param('rtwdemo_roll/RollAngleReference/LoThr','Value','LoThrParam')
% evalc('rtwbuild(''rtwdemo_roll'')');
% %%
% % The file |rtwdemo_roll.c| defines |UpThrParam| and |LoThrParam| as separate global variables. 
% % Pragmas specify that the build toolchain allocate memory in the
% % |MYALGORITHM_DATA| section.
% rtwdemodbtype(file,'/* Exported data definition */','/* Block states (default storage) */',1,0)

%% 
% Copyright 2012 The MathWorks, Inc.