%% Generate Reusable Code from Model Reference Hierarchy
% A reusable subsystem function that has input or output connected to the root 
% Inport or Outport block of a referenced model can impact code reuse. It 
% can prevent you from reusing atomic subsystems in a reference model 
% context in the same way you might reuse the subsystems in a standalone 
% model. 
%
% This example shows how to generate reusable code when you have a 
% reusable subsystem referenced inside Model block.

% Copyright 2020 The MathWorks, Inc.

%% Generate Reusable Code for Subsystem
% 1. Convert these blocks into a subsystem. Drag a box to outline the 
%    subsystem that you want to create. From the *Multiple* tab on the
%    Simulink Editor toolstrip, select *Create Subsystem*.
open_system('ex_codeReuseSubsys')
%%
% 2. Make these changes to the Subsystem block parameters:
%
% * Select <docid:simulink_ref#brp1xt9-56 *Treat as atomic unit*>.
% * On the *Code Generation* tab, set <docid:simulink_ref#brp1xt9-91 
%   *Function packaging*> to |Reusable function|.

%%
% 3. Create a model that includes three instances of the preceding
% subsystem.
open_system('ex_codeReuseThreeSubsys')

%%
% 4. Set the model configuration parameter <docid:rtw_ref#bq7cq12-1 *Default 
%    parameter behavior*> to |Inlined|.
%
% 5. To build the model and generate code, press *Ctrl+B*.
evalc('rtwbuild(''ex_codeReuseThreeSubsys'')'); 

%%
% The code generator optimizes the code by generating one copy of the 
% function for the reused subsystem in the |model.c| file.
file = fullfile('ex_codeReuseThreeSubsys_grt_rtw','ex_codeReuseThreeSubsys.c');
rtwdemodbtype(file,'void ex_codeReuseThreeSubsys_Subsystem1', ...
    '/* Model step function */',1,0);

%% Generate Reusable Code for Subsystem in Referenced Model
% 1. Create a top model by using a Model block that references the preceding 
%    model that has three instances of the reusable subsystem.
open_system('ex_codeReuseTopModel')

%%
% 2. Generate code for the top model. The code generator generates three 
%    different function signatures in the |slprj| folder.
evalc('rtwbuild(''ex_codeReuseTopModel'')');

file = fullfile('slprj/grt/ex_codeReuseThreeSubsys','ex_codeReuseThreeSubsys.c');
rtwdemodbtype(file,'/* Output and update for atomic system: ', ...
    '/* Output and update for referenced model',1,0);
%%
% 3. To enable the subsystem functions for code reuse, insert Signal
%    Conversion blocks into the referenced model. Place one block between the Inport 
%    and Subsystem 1 and another block between Subsystem 3 and the Outport. 
open_system('ex_codeReuseSubsysSigConvert')

%%
% If the subsystem has a Merge block with initial conditions, do not add a 
% Signal Conversion block. Instead, add a Bias block to obtain a reusable function.
%
% 4. Select the model configuration parameter <docid:simulink_gui#bq8t8ov-1 
%    *Pass fixed-size scalar root inputs by value for code generation*>.
%
% 5. Generate code for the top model. The code generator generates a single 
%    reusable function in the |slprj| folder.
set_param('ex_codeReuseTopModel/Model','ModelFile','ex_codeReuseSubsysSigConvert')

evalc('rtwbuild(''ex_codeReuseTopModel'')');

file = fullfile('slprj/grt/ex_codeReuseSubsysSigConvert','ex_codeReuseSubsysSigConvert.c');
rtwdemodbtype(file,'void ex_codeReuseSubsysSigConvert_Subsystem1', ...
    '/* Output and update for referenced model',1,0);