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® Excel® workbook.
Navigate to the folder matlabroot/examples/ecoder
(open). Copy this file to a writable, working folder:
ex_ICD_PCG.xls
Navigate to the folder matlabroot/examples/ecoder/main
(open). Copy this file to the same writable, working folder:
ex_importICD_PCG.m
In Microsoft® Excel® or another compatible program, open the ex_ICD_PCG.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
.
Some data items in the ICD belong to other component
, which is a component that exists outside of MATLAB. Create the code files that define and declare this external data.
Create the source file ex_inter_sigs.c
in your current folder. This file defines the imported signal sensors
.
#include "ex_inter_sigs.h" EngSensors sensors; /* Instrument measurements. */
Create the header file ex_inter_sigs.h
in your current folder.
#include "ex_inter_types.h" extern EngSensors sensors; /* Instrument measurements. */
Create the header file ex_inter_types.h
in your current folder. This file defines the structure type EngSensors
and numeric data types such as u8En7
.
#ifndef INTER_TYPES_H__ #define INTER_TYPES_H__ typedef short s16En3; typedef short s16En7; typedef unsigned char u8En7; typedef short s16En15; /* Structure type for instrument measurements. */ typedef struct { /* Throttle angle. */ s16En3 throttle; /* Engine speed. */ s16En3 speed; /* EGO sensors. */ s16En7 ego; /* Manifold pressure. */ u8En7 map; } EngSensors; #endif
Run the script prepare_sldemo_fuelsys_dd
. The script prepares a system model, sldemo_fuelsys_dd
, for this example.
run(fullfile(matlabroot,'examples','ecoder','main','prepare_sldemo_fuelsys_dd'))
Open the system model, sldemo_fuelsys_dd
.
sldemo_fuelsys_dd
This system model references a controller model. In this example, you generate code from the controller model.
Open the controller model, sldemo_fuelsys_dd_controller
.
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.
To configure code generation settings for the data items, import the settings from the ICD.
Open the example script ex_importICD_PCG
. 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('ex_importICD_PCG')
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 ex_importICD_PCG
script.
run('ex_importICD_PCG')
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.
Configure the controller model to compile the generated code into an executable by clearing the model configuration parameter Generate code only.
Generate code from the controller model.
### Starting build procedure for model: sldemo_fuelsys_dd_controller ### Successful completion of build procedure for model: sldemo_fuelsys_dd_controller
The generated header file sldemo_FuelModes.h
defines the enumeration sldemo_FuelModes
.
typedef enum { LOW = 1, /* Default value */ RICH, DISABLED } sldemo_FuelModes;
The file sldemo_fuelsys_dd_controller_types.h
includes (#include
) the external header file ex_inter_types.h
, which defines data types such as u8En7
and the structure type EngSensors
.
#include "ex_inter_types.h"
The file sldemo_fuelsys_dd_controller_private.h
includes the header file ex_inter_sigs.h
. This external 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.
/* Exported data declaration */ /* Declaration for custom storage class: ExportToFile */ extern u8En7 PressEst[855]; /* Referenced by: '<S6>/Pressure Estimation' */ /* Lookup table to estimate pressure on sensor failure. */ extern s16En15 PumpCon[551]; /* Referenced by: '<S1>/Pumping Constant' */ /* Lookup table to determine pumping constant based on measured engine speed and manifold pressure. */ extern s16En15 RampRateKiZ[25]; /* Referenced by: '<S1>/Ramp Rate Ki' */ /* Lookup table to determine throttle rate. */ extern s16En3 SpeedEst[1305]; /* Referenced by: '<S7>/Speed Estimation' */ /* Lookup table to estimate engine speed on sensor failure. */ extern s16En7 ThrotEst[551]; /* Referenced by: '<S8>/Throttle Estimation' */ /* Lookup table to estimate throttle angle on sensor failure. */ extern sldemo_FuelModes fuel_mode; /* '<Root>/control_logic' */ /* Fueling mode of engine. Enrich air/fuel mixture on sensor failure. */ extern int16_T fuel_rate; /* '<S10>/Merge' */
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
.
s16En15 RampRateKiZ[25] = { 393, 786, 1180, 1573, 1966, 786, 1573, 2359, 3146, 3932, 1180, 2359, 3539, 4719, 5898, 1573, 3146, 4719, 6291, 7864, 1966, 3932, 5898, 7864, 9830 } ; /* Referenced by: '<S1>/Ramp Rate Ki' */
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.
/* SwitchCase: '<S10>/Switch Case' incorporates: * Constant: '<S11>/shutoff' */ switch (fuel_mode) { case LOW: /* Outputs for IfAction SubSystem: '<S10>/low_mode' incorporates: * ActionPort: '<S12>/Action Port' */ /* DiscreteFilter: '<S12>/Discrete Filter' incorporates: * DiscreteIntegrator: '<S1>/Discrete Integrator' */ DiscreteFilter_tmp = (int16_T)(int32_T)((int32_T)((int32_T)((int32_T) rtDWork.DiscreteIntegrator_DSTATE << 14) - (int32_T)(-12137 * (int32_T) rtDWork.DiscreteFilter_states_g)) >> 14);
When you make changes to the ICD, you can reuse the ex_importICD_PCG
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 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 ex_importICD_PCG
script.
Generate code from the model.
### Starting build procedure for model: sldemo_fuelsys_dd_controller ### Successful completion of build procedure for model: sldemo_fuelsys_dd_controller
The generated file exported_types.h
defines the structure type EngSensors
and the fixed-point data types.
typedef int16_T s16En3; typedef int16_T s16En7; typedef uint8_T u8En7; /* Structure type for instrument measurements. */ typedef struct { /* Throttle angle. */ s16En3 throttle; /* Engine speed. */ s16En3 speed; /* EGO sensors. */ s16En7 ego; /* Manifold pressure. */ u8En7 map; } EngSensors; typedef int16_T s16En15;
The file signals.c
now includes the definition of the signal sensors
.
/* Exported data definition */ /* Definition for custom storage class: ExportToFile */ sldemo_FuelModes fuel_mode; /* '<Root>/control_logic' */ /* Fueling mode of engine. Enrich air/fuel mixture on sensor failure. */ int16_T fuel_rate; /* '<S10>/Merge' */ /* Fuel rate setpoint. */ EngSensors sensors; /* '<Root>/sensors' */
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
, 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 sysDict
and click Save.
Click Migrate data.
Click Change all models in response to the message about using the dictionary for referenced models.
Click Migrate in response to the message about copying referenced variables.
The variables and objects that the models use exist in the new data dictionary sysDict.sldd
, which is in your current folder. The three models in the model reference hierarchy are linked to this dictionary.
You can import the definition of the enumerated type sldemo_FuelModes
into the controller dictionary. See Enumerations in Data Dictionary.
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 Store Design Attributes of Signals and States.