11 KiB
TargetLink Enumerations
[TOC]
As of TargetLink version 4.3, there is support for using enumerations in Simulink models and generated code. This section describes how to use this new feature.
Defining an Enumeration
All enumerations must be defined as Matlab classes, inheriting from the Simulink.IntEnumType class. These files should be placed in the same folder, e.g. Models/Common/VcEnumDefinitions. This makes them easy to find and keep unique. Unique enumeration definitions are required. The name of the enumeration must match the name of the file.
Matlab enumeration template:
classdef SomeEnumName < Simulink.IntEnumType
%SOMEENUMNAME SomeEnumName enumeration
enumeration
MemberOne(0)
MemberTwo(1)
MemberThree(2)
end
methods (Static)
function retVal = getDescription()
retVal = 'SomeEnumName';
end
function retVal = getDefaultValue()
retVal = SomeEnumName.MemberOne;
end
function retVal = getDataScope()
retVal = 'Exported';
end
function retVal = addClassNameToEnumNames()
retVal = true;
end
end
end
Using an Enumeration
When the enumeration is defined, it can be used in, for example, an inport or a constant block. Many TargetLink blocks accept enumeration type inputs, such as TL_MultiPortSwitch and TL_RelationalOperator.
To get the enumeration in the code, the data type IMPLICIT_ENUM must be chosen in the Type field, in the TargetLink block. Additionally, the name of the enumeration must be specified in the Unit field in the TargetLink block, together with the prefix "-,$". For example, "-,$DtElecThermSt". Signals must specify the quantity "_Enm_" in the name, e.g. sVcModelName_Enm_Dummy.
In- and Out-ports
Constants
This sections provides examples for constants with different variable classes.
Default
This class only works on constants on the top most layer of the model.
CVC_VAR
This class generates the same code as the default class does. There is no need for a name as the code produces pure string values.
A CVC_VAR constant compared with an input of the same enumeration:
/* Relational: VcModelName/VcModelName/6_ControllerRequestForSecondRowWhenNotFourZoneCont
rol/Relational Operator2 */
SModelName10___ional_Operator2 = CLIMACFGFORNROFTSETG_NROFTSETG2 ==
sVcModelNameTwo_Enm_CatcCfgForNrOfTSetg;
CVC_CONST
This class generates a constant. The constant values does not come from the Matlab workspace, it does not exist in any _par.m file. Instead, it is loaded in the memory as a Simulink class after running Init_PyBuild.m.
A CVC_CONST constant compared with an input of the same enumeration:
if (cEnm_ClimaCfgForNrOfTSetg1_NrOfTSetg1 == sVcModelNameTwo_Enm_CatcCfgForNrOfTSetg) {
/* Switch: VcModelName/VcModelName/6_ControllerRequestForSecondRowWhenNotFourZoneCo
ntrol/Switch5
# combined # Switch: VcModelName/VcModelName/7_ManualOverrideOfActuatorRequest/S
witch1 */
SModelName11_Switch1 = SModelName9_Switch2[0];
}
Definition:
CVC_CONST ClimaCfgForNrOfTSetg cEnm_ClimaCfgForNrOfTSetg1_NrOfTSetg1 =
CLIMACFGFORNROFTSETG_NROFTSETG1; /*
Unit: -,$ClimaCfgForNrOfTSetg
MIN/MAX: 0 .. 0 */
CVC_CAL
This class generates a calibratable constant.
A CVC_CAL constant compared with an input of the same enumeration:
/* Relational: VcModelName/VcModelName/6_ControllerRequestForSecondRowWhenNotFourZoneCont
rol/Relational Operator1 */
SModelName10___ional_Operator1 = sVcModelNameTwo_Enm_CatcCfgForNrOfTSetg ==
cVcModelName_Enm_ClimaCfgForNrOfTSetg1_NrOfTSetg3;
}
Definition:
CVC_CAL ClimaCfgForNrOfTSetg cVcModelName_Enm_ClimaCfgForNrOfTSetg1_NrOfTSetg3 =
CLIMACFGFORNROFTSETG_NROFTSETG3; /* Unit: -,$ClimaCfgForNrOfTSetg */
Note that the block name in this example starts with "Enm_".
Generated Files
This section describes what happens when TargetLink generates source files.
Code
When TargetLink generates code, it creates a new file, e.g. udt_ModelName.h, where it defines all enumerations which the model uses. The text values of the enumeration members are used in the code.
Code snippets:
udt_ModelName.h
/**************************************************************************************************\
***
*** Simulink model : VcModelName_OPortMvd
*** TargetLink subsystem : VcModelName_OPortMvd/VcModelName
*** Codefile : udt_ModelName.h
***
*** Generation date: 2020-11-30 16:10:50
***
*** TargetLink version : 4.3p3 from 16-Oct-2018
*** Code generator version : Build Id 4.3.0.27 from 2018-09-24 17:55:03
\**************************************************************************************************/
#ifndef UDT_MODELNAME_H
#define UDT_MODELNAME_H
#include "tl_basetypes.h"
typedef enum DtElecThermSt_tag {
DTELECTHERMST_DTELECCOOLG = 0,
DTELECTHERMST_DTELECPASCOOLG = 1,
DTELECTHERMST_DTELECHEATG = 2,
DTELECTHERMST_DTELECPASHEATG = 3,
DTELECTHERMST_DTELECACTVHEATG = 4,
DTELECTHERMST_DTELECPASACTVHEATG = 5,
DTELECTHERMST_DEGAS = 6,
DTELECTHERMST_FAILSAFE = 7
} DtElecThermSt; /* Description: Enumeration type derived from Simulink type DtElecThermSt */
VcModelName.h
/**************************************************************************************************\
CVC_EXT: CVC external interface input variables | Width: N.A.
\**************************************************************************************************/
CVC_EXT DtElecThermSt sVcModelNameThree_Enm_DtElecThermSt; /*
Unit: -,$DtElecThermSt
Description: Electric drive coolant circuit thermal status: 'DtElecPasCoolg', 'DtElecPasHeatg', '
DtElecPasActvHeatg', 'DtElecPas' */
CVC_EXT HvBattThermSt sVcModelNameThree_Enm_HvBattThermSt; /*
Unit: -,$HvBattThermSt
Description: HV battery coolant circuit thermal status: 'HvBattOff', 'HvBattActvHeatgFromClima',
'HvBattBal', 'HvBattActvCoolg', 'HvBattPasCoolg', 'HvBattPasActvCoolg', 'HvBattPasHeatg', 'HvBatt
PasActvHeatgFromClima', 'HvBattPasActvHeatgFromDtElec', 'HvBattPasActvHeatgFromDtElecAndClima' */
VcModelName.c
/* Multiport switch: VcModelName/VcModelName/8_VlvCtrl/81_V1RadiatorBypassValveControl/
MultiportSwitch3 */
switch (sVcModelNameThree_Enm_DtElecThermSt) {
case DTELECTHERMST_DTELECPASHEATG: {
SModelName115_MultiportSwitch3 = 1;
break;
}
case DTELECTHERMST_DTELECPASACTVHEATG: {
SModelName115_MultiportSwitch3 = 1;
break;
}
default: {
SModelName115_MultiportSwitch3 = 0;
break;
}
}
A2L Files
The unit A2L-files are updated automatically with enumeration definitions.
JSON Configuration Files
The data type of each enumeration type signal will be the name of the corresponding enumeration. Note that the data type is set to IMPLICIT_ENUM in the TargetLink block.
The default value of the enumeration will be inserted into the configuration file, based on the return value of getDefaultValue() in the enumeration definition m-file.
powertrain-build
When powertrain-build builds a project, see Detailed build options, it will parse all udt_VcModel.h and json configuration files in order to get information about used enumerations in the project.
This information is used to:
- Make sure that the same model does not define the same enumeration twice.
- This is probably unnecessary. Two enumerations with the same name cannot exist in Simulink at the same time.
- Make sure that two (or more) models does not define the same enumeration differently.
- This can occur if an enumeration definition is updated without updating generated files based on the old definition.
- Define missing enumeration type signals in VcDummy_spm.c/h.
Interface enumerations are also compared with the parsed project enumerations to make sure they are defined correctly.
Old default value extraction
Below method was used before the default values were inserted into the json configuration file, during code generation. It will stay as a fall back for a while, until all model-configuration files have been updated with the default value.
To be able to extract the default values for each enumeration powertrain-build must know the path to the common enumeration class folder. The path is set with the key "enumDefDir" in the ProjectCfg.json file.
{
"ConfigFileVersion": "0.2.1",
"BaseConfig" : "../../../ConfigDocuments/BaseConfig.json",
"ProjectInfo" : {
"yamlInterface": true,
"projConfig" : "Dummy",
"a2LFileName": "SPM.a2l",
"ecuSupplier" : "Dummy",
"ecuType" : "",
"unitCfgDeliveryDir": "./output/UnitCfgs",
"configDir": "ConfigDocuments",
"prjCodeswitches": "Codeswitch_Setup*.csv",
"commonSrcDir": "../../../Models/Common/pybuild_src",
"prjUnitSrcDir": "../../../Models/*/Vc*/pybuild_src",
"prjUnitCfgDir": "../../../Models/*/Vc*/pybuild_cfg",
"prjUnitMdlDir": "../../../Models/*/Vc*",
"enumDefDir": "../../../Models/Common/VcEnumDefinitions"
.
.
.
Requirements
- Enumerations must be defined as Matlab classes, inheriting from the Simulink.IntEnumType class.
- Enumeration class files must have the same name as the enumeration it defines.
- Enumeration class files must be placed in a common folder.
- Enumerations are uniquely defined.
- To get the enumeration in the code, the data type IMPLICIT_ENUM must be selected in the TargetLink block.
- The name of the enumeration must be specified in the Unit field in the TargetLink block, prefixed with "-,$".
- Signals must specify the quantity "_Enm_" in the name.
- Interface enumerations must be defined in the interface_data_types.yml file, located in the conf.local project folder.
Pitfalls
When TargetLink generates the A2L-file, it must know the underlying data type to use. The underlying data type is calculated based on the number of enumeration members and their values. When powertrain-build parses the enumeration it does not know about the underlying data type. Therefore, it must calculate the underlying data type too. This is done in a separate function.
The underlying data type calculations are based on how the compiler would choose a fitting data type, given an enumeration. The smallest underlying data type which can be chosen is an 8 bit integer, two bytes. Some compilers may perform optimization using only one byte. If the software compiles enumerations using one byte, while the A2L-files states they are two bytes, what will happen when calibrating the software?
What is the underlying data type of enumerations entering an app? CS software homepage (based on ARXML from a database?) seems to specify signed 8 bit integers. Can this cause issues?
Summary
- If one of the functions for calculating the underlying data type is changed, the other must be changed too.
- Potential software calibration issues, A2L versus compile sofware enumeration sizes.
- Actual data types of enumerations entering an app?