www.gusucode.com > ecoder 案例源码程序 matlab代码 > ecoder/ConfigGenCodeAccordingToICDExample.m

    %% Configure Generated Code According to Interface Control Document
% Import specifications from an interface control
% document (ICD), configure code generation settings for a model according
% to the specifications, and store the settings in data dictionaries. 
%
% An ICD describes the data interface between two software components. To
% exchange and share data, the components declare and define global
% variables that store signal and parameter values. The ICD names the
% variables and lists characteristics such as data type, physical units,
% and parameter values. When you create models of the components in
% Simulink, you can configure the generated code to conform to the
% interface specification.
%
% In this example, the ICD is a Microsoft(R) Excel(R) workbook.
%% Explore Interface Control Document
% Navigate to the folder
% |_matlabroot_/examples/ecoder|
% (<matlab:cd(fullfile(matlabroot,'examples','ecoder')) open>). Copy these
% files to a writable, working folder:
%
% * |ICD.xls|
% * |importICD.m|
%
% In Microsoft(R) Excel(R) or another compatible program, open the |ICD.xls| workbook
% and view the first worksheet, |Signals|. Each row of the worksheet
% describes a signal that crosses the interface boundary.
%
% Inspect the cell values in the worksheet. The |Owner| column indicates
% the name of the component that allocates memory for each signal. The
% |DataType| column indicates the signal data type in memory. For example,
% the worksheet uses the expression |Bus: EngSensors| to represent a
% structure type named |EngSensors|.
%
% In the |Parameters| worksheet, the |Value| column indicates the value
% of each parameter. If the value of the parameter is nonscalar, the value
% is stored in its own separate worksheet, which has the same name as the
% parameter.
%
% In the |Numeric Types| worksheet, each row represents a named numeric
% data type. In this ICD, the data use fixed-point data types (Fixed-Point
% Designer). The |IsAlias| column indicates whether the C code uses
% the name of the data type (for example, |u8En7|) or uses the name of the
% primitive integer data type that corresponds to the word length. The
% |DataScope| column indicates whether the generated code exports or
% imports the definition of the type.
%
% In the |Structure Types| worksheet, each row represents either a
% structure type or a field of a structure type. For structure types, the
% value in the |DataType| column is |struct|. Subsequent rows that do not
% use |struct| represent fields of the preceding structure type. This ICD
% defines a structure type, |EngSensors|, with four fields: |throttle|,
% |speed|, |ego|, and |map|.
%
% In the |Enumerated Types| worksheet, similar to the |Structure Types|
% worksheet, each row represents either an enumerated type or an
% enumeration member. This ICD defines an enumerated type
% |sldemo_FuelModes|.
%% Write Custom Code
% Some data items in the ICD belong to |other component|, which is a
% component that exists outside of MATLAB. Create the custom code files
% that define and declare this external data.
% 
% Create the custom source file |inter_sigs.c| in your current folder. This
% file defines the imported signal |sensors|.
%
% <include>inter_sigs.c</include>
%
% Create the custom header file |inter_sigs.h| in your current folder.
%
% <include>inter_sigs.h</include>
%
% Create the custom header file |inter_types.h| in your current folder.
% This file defines the structure type |EngSensors| and numeric data types
% such as |u8En7|.
%
% <include>inter_types.h</include>
%% Explore Example Model
% Run the script <matlab:run(fullfile(matlabroot,'examples','ecoder','prepare_sldemo_fuelsys_dd'))
% |prepare_sldemo_fuelsys_dd|>. The script prepares a system model,
% |sldemo_fuelsys_dd|, for this example.
%
%   run(fullfile(matlabroot,'examples','ecoder','prepare_sldemo_fuelsys_dd'))
prepare_sldemo_fuelsys_dd
%%
% Open the system model, <matlab:sldemo_fuelsys_dd |sldemo_fuelsys_dd|>.
%
%   sldemo_fuelsys_dd
open_system('sldemo_fuelsys_dd')
%%
% This system model references a controller model. In this example, you
% generate code from the controller model.
%
% Open the controller model, <matlab:sldemo_fuelsys_dd_controller
% sldemo_fuelsys_dd_controller>.
%
%   sldemo_fuelsys_dd_controller
open_system('sldemo_fuelsys_dd_controller')
%%
% Data items in the controller model refer to |Simulink.Signal| and
% |Simulink.Parameter| objects in the base workspace. For example, the
% input signal |sensors| refers to a |Simulink.Signal| object that has the
% same name. These objects store settings such as data types, block
% parameter values, and physical units. The names of these data items and
% objects match the names of the signals and parameters in the ICD.
%% Import ICD Specifications into Simulink
% To configure code generation settings for the data items, import
% the settings from the ICD.
%
% Open the example script
% <matlab:edit('importICD')
% |importICD|>. The script imports the data from each worksheet of the ICD
% into variables in the base workspace. It then configures the properties
% of the |Simulink.Signal| and |Simulink.Parameter| objects in the base
% workspace by using the imported data.
%
%   edit('importICD')
%
% If the base workspace already contains a data object that corresponds to
% a target data item in the ICD, the script configures the properties of
% the existing object. If the object does not exist, the script creates the
% object.
%
% Run the |importICD| <matlab:run('importICD') script>.
%
%   run('importICD')
%
% The script configures the data objects in the base workspace for code
% generation according to the specifications in the ICD. The |Simulink.Bus|
% object |EngSensors| represents the structure type from the ICD. The
% |Simulink.NumericType| objects, such as |u8En7|, represent the
% fixed-point data types.
importICD
%% Generate and Inspect Code
% Configure the controller model to compile the generated code into an
% executable by clearing the model configuration parameter *Generate code
% only*.
set_param('sldemo_fuelsys_dd_controller','GenCodeOnly','off')
%%
% Generate code from the controller model.
rtwbuild('sldemo_fuelsys_dd_controller')
%%
% The generated header file |sldemo_FuelModes.h| defines the enumeration
% |sldemo_FuelModes|.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_FuelModes.h');
rtwdemodbtype(file,'typedef enum {','} sldemo_FuelModes;',1,1)
%%
% The file |sldemo_fuelsys_dd_controller_types.h| includes (|#include|) the
% custom header file |inter_types.h|, which defines data types such as
% |u8En7| and the structure type |EngSensors|.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_fuelsys_dd_controller_types.h');
rtwdemodbtype(file,'#include "inter_types.h"','#include "inter_types.h"',1,1)
%%
% The file |sldemo_fuelsys_dd_controller_private.h| includes the custom
% header file |inter_sigs.h|. This custom header file contains the |extern|
% declaration of the signal |sensors|, which a different software component
% owns.
%
% The data header file |global_data.h| declares the exported parameters and
% signals that the ICD specifies. To share this data, other components can
% include this header file.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw','global_data.h');
rtwdemodbtype(file,'/* Exported data declaration */',...
    '/* Fuel rate setpoint. */',1,1)
%%
% The data definitions (memory allocation) appear in the source files that
% the ICD specifies, |params.c| and |signals.c|. For example, |params.c| defines and
% initializes the parameter |RampRateKiZ|.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw','params.c');
rtwdemodbtype(file,'s16En15 RampRateKiZ[25]',...
    '/* Lookup table to determine throttle rate. */',1,1)
%%
% The algorithm is in the model |step| function in the file
% |sldemo_fuelsys_dd_controller.c|. The algorithm uses the global data that
% the ICD identifies. For example, the algorithm uses the value of the
% signal |fuel_mode| in a |switch| block to control the flow of execution.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_fuelsys_dd_controller.c');
rtwdemodbtype(file,'/* SwitchCase: ''<S10>/Switch Case'' incorporates:',...
    '/* Sum: ''<S12>/Sum3'' incorporates:',1,0)
%% Change Ownership of Data in ICD
% When you make changes to the ICD, you can reuse the |importICD| script
% to reconfigure the model. Change the ownership of the signal
% |sensors|, the structure type, and the fixed-point data types from
% |other_component| to |sldemo_fuelsys_dd_controller|.
%
% In the ICD, on the |signals| worksheet, for the signal |sensors|, set
% these cell values:
%
% * |Owner| to |sldemo_fuelsys_dd_controller|
% * |HeaderFile| to |global_data.h|
% * |DefinitionFile| to |signals.c|
%
% On the |Numeric Types| worksheet, for all of the fixed-point data types,
% set:
%
% * |DataScope| to |Exported|
% * |HeaderFile| to |exported_types.h|.
%
% On the |Structure Types| worksheet, for the structure type |EngSensors|,
% set:
%
% * |DataScope| to |Exported|
% * |HeaderFile| to |exported_types.h|.
%
% Rerun the |importICD| script.
[~, ~, sigsRaw] = xlsread(xlsFileName,'Signals','');
[~, ~, numTypesRaw] = xlsread(xlsFileName,'Numeric Types','');
[~, ~, structTypesRaw] = xlsread(xlsFileName,'Structure Types','');
 
sigsBackup = sigsRaw;
numTypesBackup = numTypesRaw;
structTypesBackup = structTypesRaw;
 
sigsRaw{2,5} = 'sldemo_fuelsys_dd_controller';
sigsRaw{2,6} = 'global_data.h';
sigsRaw{2,7} = 'signals.c';
 
for i = 2:5
    numTypesRaw{i,2} = 'Exported';
    numTypesRaw{i,3} = 'exported_types.h';
end
 
structTypesRaw{2,3} = 'Exported';
structTypesRaw{2,4} = 'exported_types.h';
 
xlswrite(xlsFileName,sigsRaw,'Signals');
xlswrite(xlsFileName,numTypesRaw,'Numeric Types');
xlswrite(xlsFileName,structTypesRaw,'Structure Types');
 
importICD;
%%
% Generate code from the model.
rtwbuild('sldemo_fuelsys_dd_controller')
%%
% The generated file |exported_types.h| defines the structure type
% |EngSensors| and the fixed-point data types.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'exported_types.h');
rtwdemodbtype(file,'typedef int16_T s16En3;','#endif',1,0)
%%
% The file |signals.c| now includes the definition of the signal |sensors|.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'signals.c');
rtwdemodbtype(file,'/* Exported data definition */','EngSensors sensors;',1,1)
% This extra code is here to prevent Example Manager from uploading the
% edited ICD.xls.
xlswrite(xlsFileName,sigsBackup,'Signals');
xlswrite(xlsFileName,numTypesBackup,'Numeric Types');
xlswrite(xlsFileName,structTypesBackup,'Structure Types');
%% Migrate Base Workspace Data to Data Dictionary
% Objects and variables that you create in the base workspace (for example,
% |Simulink.Parameter| objects) are not saved with the model. When you end
% your MATLAB session, the objects and variables do not persist. To
% permanently store the objects and variables, link one or more models to
% one or more data dictionaries.
%
% Data dictionaries also enable you to track changes made to the objects and
% variables, which helps you to:
%
% * Reconcile the data stored in MATLAB with the data stored in the ICD.
% * Export data from MATLAB to the ICD.
%
% # In the top model, |sldemo_fuelsys_dd|, select *File > Model Properties
% > Link to Data Dictionary*.
% # In the Model Properties dialog box, select *Data Dictionary*. Click
% *New*.
% # In the Create a new Data Dictionary dialog box, set *File name* to
% |sysDict| and click *Save*.
% # In the Model Properties dialog box, click *OK*.
% # Click *Yes* in response to the message about migrating base workspace
% data.
% # Click *Yes* in response to the message about removing the imported
% items from the base workspace.
% # Click *OK* in response to the message about enumerated type migration.
%
% The variables and objects that the models use all exist in the new data
% dictionary |sysDict.sldd|, which is in your current folder. All three
% models in the model reference hierarchy are linked to this dictionary.
usedVars = {Simulink.findVars('sldemo_fuelsys_dd',...
    'SourceType','base workspace','SearchReferencedModels','on').Name};
sysDictObj = Simulink.data.dictionary.create('sysDict.sldd');
modelNames = find_mdlrefs('sldemo_fuelsys_dd');
for i = 1:length(modelNames)
    set_param(modelNames{i},'DataDictionary','sysDict.sldd')
end
importFromBaseWorkspace(sysDictObj,'clearWorkspaceVars',true,'varList',usedVars);
%% Create Reference Dictionary
% To establish clear ownership of the data that you store in a dictionary,
% create reference dictionaries.
%
% # Open the controller model, |sldemo_fuelsys_dd_controller|. Select *File
% > Model Properties > Link to Data Dictionary*. Click *New*.
% # Set the name of the new dictionary to |ctrlDict.sldd| and click *Save*.
% In the Model Properties dialog box, click *OK*.
% # In response to the message about changing the dictionary or moving the
% data, click *Move Data*. Click *Yes* in response to the message about
% migrating data.
% 
% The variables and objects that the controller model uses now exist in the
% referenced dictionary |ctrlDict.sldd|. Because |sysDict.sldd| references
% |ctrlDict.sldd|, you can view all of the data by opening |sysDict.sldd|
% in the Model Explorer.
%
% Now that the model data acquire code generation settings from objects and
% variables that are stored in data dictionaries, you can modify the
% |importICD| script so it
% accesses the dictionaries instead of the base workspace.
% For more information about the programmatic interface for data
% dictionaries, see <docid:simulink_ug.bunkch6-1>.
ctrlDictObj = Simulink.data.dictionary.create('ctrlDict.sldd');
addDataSource(sysDictObj,'ctrlDict.sldd');
dDataSectObj = getSection(sysDictObj,'Design Data');
usedVars = {Simulink.findVars('sldemo_fuelsys_dd_controller',...
    'SourceType','data dictionary').Name};
for i = 1:length(usedVars)
        entry = getEntry(dDataSectObj,usedVars{i});
        entry.DataSource = 'ctrlDict.sldd';
end
set_param('sldemo_fuelsys_dd_controller','DataDictionary','ctrlDict.sldd')
saveChanges(ctrlDictObj)
%% Store Enumerated Type Definition in Data Dictionary
% You can import the definition of the enumerated type |sldemo_FuelModes|
% into the controller dictionary. See <docid:simulink_ug.bukuj7i>.
%% Store Signal and State Design Attributes Inside or Outside of Model File
% In this example, you use |Simulink.Signal| objects to specify design
% attributes such as data types, minimum and maximum values, and physical
% units. The signal objects store these specifications outside of the model
% file. 
%
% Alternatively, you can store these specifications in the model file
% by using block and port parameters, which you can access through the
% Model Data Editor, the Property Inspector, and other dialog boxes. 
%
% To
% decide where to store the specifications, see
% <docid:simulink_ug.bvcdbmy>.