Replace and Rename Simulink Coder Data Types to Conform to Coding Standards
If the Data type replacement configuration parameter is set to
Use coder typedefs
, the generated code uses Simulink®
Coder™ data type aliases such as real_T
and
int32_T
. The code uses these aliases to define global and local
variables. If your coding standards require that you use other data type aliases,
including aliases that your existing code defines, you can:
Configure data type replacement for the entire model.
Configure individual data items (such as signals, parameters, and states) to use specific data type aliases.
For information about controlling data types in a model, see Control Data Types of Signals.
Inspect External C Code
Save this C code into a file named my_types.h
in your current
folder. This file represents a header file in your existing code that defines custom
data type aliases by using typedef
statements.
#include <stdbool.h> typedef double my_dblPrecision; typedef short my_int16; typedef bool my_bool;
Explore Example Model and Default Generated Code
Open the example model ex_data_type_replacement
open_system('ex_data_type_replacement')
Open the Embedded Coder app.
Select Code Interface > Default Code Mappings.
On the Signals/States tab, the Storage Class column shows that named signal lines such as
temp
use the storage classExportedGlobal
. With this setting, the signal lines appear in the generated code as separate global variables.On the Modeling tab, click Model Data Editor.
In the Model Data Editor, inspect the Signals tab.
Set the Change view drop-down list to
Design
.Update the block diagram. Simulink assigns a specific data type to each signal that uses an inherited data type setting such as
Inherit: Inherit via internal rule
.In the data table, expand the width of the Data Type column. The column shows that the signals in the model use a mix of the data types
int16
,double
, andboolean
. You can also see these data types in the model.Generate code for the model.
In the code generation report, inspect the shared utility file rtwtypes.h
. The code uses typedef
statements to rename the primitive C data types by using standard Simulink Coder™ aliases. For example, the code renames the primitive type double
by using the alias real_T
.
typedef double real_T;
Inspect the file ex_data_type_replacement.c
. The code uses the default data type aliases to declare and define variables. For example, the code uses the data types real_T
, int16_T
, and boolean_T
to define the global variables flowIn
, temp
, and intlk
.
real_T flowIn; /* '<Root>/In3' */ int16_T temp; /* '<Root>/Add2' */ boolean_T intlk; /* '<S1>/Compare' */
The model step
function defines local variables by using the same data type aliases.
real_T rtb_Add; real_T rtb_FilterCoefficient;
Reuse External Data Type Definitions
Configure the generated code to define variables by using the custom data types
defined in my_types.h
instead of the default type names.
At the command prompt, create a
Simulink.AliasType
object for each data type alias that your external code defines.Simulink.importExternalCTypes('my_types.h');
In the base workspace, the
Simulink.importExternalCTypes
function creates the objectsmy_dblPrecision
,my_int16
, andmy_bool
.For each object, the function sets the
DataScope
property to'Imported'
and theHeaderFile
property to'my_types.h'
. With these settings, the code generator does not create atypedef
statement for each object, but instead the generated code reuses the statements frommy_types.h
by including (#include
) the file.In the model's Configuration Parameters dialog box, from the Data type replacement drop-down list, select
Use coder typedefs
.Select the Specify custom data type names check box.
In the Replacement Name column, specify the values provided in this table.
Simulink Name Replacement Name double
my_dblPrecision
int16
my_int16
boolean
my_bool
Generate code from the model.
In the code generation report, inspect the file
rtwtypes.h
. Now, the code uses an#include
directive to import the contents of the external header filemy_types.h
, which contains the custom data type aliases.#include "my_types.h" /* User defined replacement datatype for int16_T real_T boolean_T */
Inspect the file
ex_data_type_replacement.c
. The code uses the custom data type aliasesmy_dblPrecision
,my_int16
, andmy_bool
to define the global variables such asflowIn
,temp
, andintlk
.my_dblPrecision flowIn; /* '<Root>/In3' */ my_int16 temp; /* '<Root>/Add2' */ my_bool intlk; /* '<S1>/Compare' */
The model
step
function defines local variables by using the custom data type aliases.my_dblPrecision rtb_Add; my_dblPrecision rtb_FilterCoefficient;
Create Meaningful Data Type Aliases for Individual Data Items
Suppose that your coding standards require that important data items use a data
type whose name indicates the real-world significance. You can create more Simulink.AliasType
objects to represent these custom
data type aliases. Use the objects to set the data types of data items in the
model.
In the Model Data Editor Data Type column, use the
Simulink.AliasType
objects to set the data types of these block outputs. You can select a signal line in the model, which highlights the corresponding row in the Model Data Editor, or search for the signals in the Model Data Editor by using the Filter contents box.Block Output Data Type Flow Setpoint flow_T
Add2 (which feeds the Compare block) diffTemp_T
Use the Model Data Editor Inports/Outports tab to set the data type of the third Inport block to
flow_T
.On the Modeling tab, under Design, click Property Inspector.
Select the block labeled Flow Controller. In the Property Inspector, click Open to open the block dialog box.
On the Data Types tab, set Sum output to
ctrl_T
. Click OK.With these data type settings, some of the named signals, such as
temp
andflowIn
, use data types that evoke real-world quantities, such as liquid flow rate and temperature.At the command prompt, create
Simulink.AliasType
objects to represent these new custom data type aliases.flow_T = Simulink.AliasType('double'); diffTemp_T = Simulink.AliasType('int16'); ctrl_T = Simulink.AliasType('double');
In the model, the signals
flowIn
andflowSetPt
use the primitive data typedouble
, so the data type aliasflow_T
maps todouble
.Update the block diagram.
Due to data type inheritance, other signals also use the custom data type aliases. For example, the output data type of the Add block fed by the third Inport block is set to
Inherit: Inherit via internal rule
. The internal rule chooses the same data type that the block inputs use,flow_T
.Generate code from the model.
The file
ex_data_type_replacement_types.h
defines the new data typesflow_T
,diffTemp_T
, andctrl_T
as aliases ofmy_dblPrecision
andmy_int16
.typedef my_dblPrecision flow_T; typedef my_int16 diffTemp_T; typedef my_dblPrecision ctrl_T;
In the file
ex_data_type_replacement.c
, the code defines global variables by using the new type names.flow_T flowIn; /* '<Root>/In3' */ flow_T flowSetPt; /* '<Root>/Flow Setpoint' */ ctrl_T flowCtrl; /* '<Root>/Interlock' */ diffTemp_T temp; /* '<Root>/Add2' */
For blocks that do not use the new data types, the corresponding generated code continues to use the replacement types that you specified earlier. For example, in the file
ex_data_type_replacement.h
, the outputs of the blocks In1 and In2 appear as structure fields that use the replacement typemy_int16
./* External inputs (root inport signals with auto storage) */ typedef struct { my_int16 In1; /* '<Root>/In1' */ my_int16 In2; /* '<Root>/In2' */ } ExtU_ex_data_type_replacement_T;
Create Single Point of Definition for Primitive Types
The custom data type aliases flow_T
and
ctrl_T
map to the primitive data type
double
. If you want to change this underlying data type from
double
to single
(float
), you must remember to modify the
BaseType
property of both Simulink.AliasType
objects.
To more easily make this change, you can create a Simulink.NumericType
object and
configure both Simulink.AliasType
objects to refer
to it. Then, you need to modify only the Simulink.NumericType
object. A Simulink.NumericType
object enables you to share a data type without
creating a data type alias.
At the command prompt, create a
Simulink.NumericType
object to represent the primitive data typesingle
.sharedType = Simulink.NumericType; sharedType.DataTypeMode = 'Single';
Configure the
Simulink.AliasType
objectsflow_T
andctrl_T
to acquire an underlying data type from this new object.flow_T.BaseType = 'sharedType'; ctrl_T.BaseType = 'sharedType';
On the Debug tab, select Information Overlays > Base Data Types Information Overlays > Alias Data Typesand (see Port Data Types). Update the block diagram.
The data type indicators in the model show that the aliases
flow_T
andctrl_T
map to the primitive typesingle
. To change this underlying primitive type, you can modify theDataTypeMode
property of theSimulink.NumericType
object,sharedType
.
By default, the Simulink.NumericType
object does
not cause another typedef
statement to appear in the generated
code.
If you generate code from the model while the Simulink.NumericType
object represents the data type
single
, the generated code maps flow_T
and
ctrl_T
to the default Simulink
Coder data type alias real32_T
, which maps to the C data
type float
. You can replace real32_T
in the
same way that you replaced real_T
, int16_T
,
and boolean_T
(Configuration Parameters > Code Generation > Data Type Replacement).
Permanently Store Data Type Objects
The Simulink.NumericType
and Simulink.AliasType
objects in the base workspace do not
persist if you end your current MATLAB® session. To permanently store these objects, consider migrating your
model to a data dictionary. See Migrate Models to Use Simulink Data Dictionary.
Create and Maintain Objects Corresponding to Multiple C typedef
Statements
To create Simulink.AliasType
objects for a large
number of typedef
statements in your external C code, consider
using the Simulink.importExternalCTypes
function.