Represent Variant Conditions of Enumerated Type in Generated Code
You can generate code from a Simulink® model using variant control variables with values of Simulink-supported enumeration types. Enumerated types improve code readability because the condition values in control expressions are represented as meaningful names instead of integers. For more information on enumeration types, see Use Enumerated Data in Simulink Models. In this section, you will learn:
How to generate C code from a model with variant conditions using enumerated types.
How the enumerated values in variant conditions are represented in the generated code.
Use Enumerated Type Derived From Built-In Integer Type
This section explains how to generate C code from a Simulink model with variant condition values of enumerated type derived from the built-in integer type int32.
Open the slexVariantSubsystems model.
model = "slexVariantSubsystems";
open_system(model)

In this model, the Controller block specifies two potential variants, the Linear controller and Nonlinear controller subsystems. The control expression for the Linear controller subsystem is V == ControllerChoice.Linear. The control expression for the Nonlinear controller subsystem is V == ControllerChoice.NonLinear.
blockPath = "slexVariantSubsystems/Controller"; lCtrlPath = model+"/Controller/Linear Controller"; nlCtrlPath = model+"/Controller/Nonlinear Controller"; set_param(lCtrlPath,"VariantControl","V == ControllerChoice.Linear"); set_param(nlCtrlPath,"VariantControl","V == ControllerChoice.Nonlinear");
Here, ControllerChoice is an integer-based enumeration class derived from the built-in data type, int32. The class is defined in the ControllerChoice.m file. The class has two enumeration values, Linear and Nonlinear. These enumerated values have underlying integer values 0 and 1.
type ControllerChoice.m
classdef ControllerChoice < int32
enumeration
Linear (0),
Nonlinear (1),
end
%All the methods below can be optionally used to configure
%the enumeration in the generated code
methods (Static = true)
%% Description of the enumeration
function retVal = getDescription()
retVal = 'Controller...';
end
%% Default value of the enumeration
function retVal = getDefaultValue()
retVal = ControllerChoice.Linear;
end
%% Specify whether the generated code imports/exports the definition
%% of the enum used in the variant control expression
function retVal = getDataScope()
retVal = 'Exported';
end
%% Get the header file to import from/export to the definition of the
%% enumeration in the generated code
function retVal = getHeaderFile()
retVal = 'Controller.h';
end
end
end
Switch Between Variant Choices and Generate Code
1. Click Simulation > Run and see the variant conditions propagate to the blocks. By default, the model use the Linear controller subsystem for simulations.
V = ControllerChoice.Linear; sim(model);
2. To modify the active choice, set the value of V to ControllerChoice.Nonlinear, then simulate the model again. The model use the Nonlinear controller subsystem during simulation.
V = ControllerChoice.Nonlinear; sim(model);
3. To generate code that chooses between variants using if and else if conditional statements, specify the Variant activation time of the Controller block to startup.
set_param(blockPath,"VariantActivationTime","startup");
4. Specify the system target configuration file as grt.tlc.
set_param(model, "SystemTargetFile","grt.tlc");
5. In the Apps tab of the toolstrip, navigate to Simulink Coder. For detailed information on settings to generate code, see Generate Code Using Simulink Coder.
6. In the C code tab, select Build > Generate code. Alternatively, enter this command in the Command Window.
slbuild(model);
### Searching for referenced models in model 'slexVariantSubsystems'. ### Total of 1 models to build. ### Starting build procedure for: slexVariantSubsystems ### Successful completion of build procedure for: slexVariantSubsystems Build Summary Top model targets: Model Build Reason Status Build Duration ======================================================================================================================== slexVariantSubsystems Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 6.3633s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 6.7189s
7. In the C Code tab, select Open Report.
8. In the slexVariantSubsystems.c file, the variable slex_V_VariantControlExpression stores the value of the variant control variable V. Its value is set to Nonlinear, which means that the Nonlinear Controller variant choice is the default active variant choice when you execute the code.
cfile=fullfile(pwd, "slexVariantSubsystems_grt_rtw", "slexVariantSubsystems.c"); coder.example.extractLines(cfile, "/* Normal MATLAB Variables with Startup variant activation time */", "/* Block states (default storage) */", 1, 0);
/* Normal MATLAB Variables with Startup variant activation time */ ControllerChoice slex_V_VariantControlExpression = Nonlinear;
9. The code also includes the variant choices Linear and NonLinear guarded by if and else if conditional statements. These conditional statements enable you to conditionally execute startup routines based on the variant condition that evaluates to true. For more information, Run Executables for Variant Blocks Without Recompiling Code for Changing Active Choices Using Startup Activation Time.
coder.example.extractLines(cfile, "/* Outputs for Atomic SubSystem: '<Root>/Controller' */", "/* End of Outputs for SubSystem: '<S1>/Nonlinear Controller' */", 1, 1);
/* Outputs for Atomic SubSystem: '<Root>/Controller' */
if (slex_V_VariantControlExpression == Linear) {
/* Outputs for Atomic SubSystem: '<S1>/Linear Controller' */
/* Update for DiscreteTransferFcn: '<S2>/Discrete Transfer Fcn' */
denAccum = (sine2 - 0.09 *
slexVariantSubsystems_DW.DiscreteTransferFcn_states[0]) - 0.5 *
slexVariantSubsystems_DW.DiscreteTransferFcn_states[1];
/* Sum: '<S2>/Add' incorporates:
* DiscreteTransferFcn: '<S2>/Discrete Transfer Fcn'
*/
rtb_VariantMergeForOutportOut1 = ((0.7 *
slexVariantSubsystems_DW.DiscreteTransferFcn_states[1] +
slexVariantSubsystems_DW.DiscreteTransferFcn_states[0]) + rtb_sine1) +
rtb_sine3;
/* Update for DiscreteTransferFcn: '<S2>/Discrete Transfer Fcn' */
slexVariantSubsystems_DW.DiscreteTransferFcn_states[1] =
slexVariantSubsystems_DW.DiscreteTransferFcn_states[0];
slexVariantSubsystems_DW.DiscreteTransferFcn_states[0] = denAccum;
/* End of Outputs for SubSystem: '<S1>/Linear Controller' */
/* End of Outputs for SubSystem: '<Root>/Controller' */
} else if (slex_V_VariantControlExpression == Nonlinear) {
/* Outputs for Atomic SubSystem: '<S1>/Nonlinear Controller' */
/* Sum: '<S3>/Add' incorporates:
* Lookup_n-D: '<S3>/1-D Lookup Table'
* Sin: '<Root>/sine2'
*/
rtb_VariantMergeForOutportOut1 = (rtb_sine1 + look1_binlxpw(sine2,
slexVariantSubsystems_ConstP.uDLookupTable_bp01Data,
slexVariantSubsystems_ConstP.uDLookupTable_tableData, 10U)) + rtb_sine3;
10. To view the definitions of Linear and Nonlinear choices, open the Controller.h file. The choices are defined using #define macros.
cfile=fullfile(pwd, "slexVariantSubsystems_grt_rtw", "Controller.h"); coder.example.extractLines(cfile, "#ifndef Controller_h_", "/* Controller_h_ */", 1, 1);
#ifndef Controller_h_ #define Controller_h_ #include "rtwtypes.h" typedef int32_T ControllerChoice; /* enum ControllerChoice */ #define Linear (0) /* Default value */ #define Nonlinear (1) #endif /* Controller_h_ */
If you are using Embedded Coder® with an ERT-based system target file, for example, ert.tlc, and you want to generate a code that encloses the Linear and Nonlinear variant choices in preprocessor conditionals #if and #elif, specify the Variant activation time parameter of the Controller block to code compile. These conditions enable you to conditionally compile variant choices as described in Compile Code Conditionally for Variations of Component Represented Using Variant Block.
Use In-Memory Enumerated Type Derived From Simulink.defineIntEnumType
This section explains how to generate code from a model having variant control variables of enumerated type derived from Simulink.defineIntEnumType.
1. Open the slexVariantSubsystems model.
open_system(model)
2. Define an in-memory enumeration class Controller using the function. The class has two enumeration values, Simulink.defineIntEnumTypeLinearChoice and NonlinearChoice. These enumerated values have underlying integer values 0 and 1.
Simulink.defineIntEnumType('Controller',... {'LinearChoice','NonlinearChoice'}, [0;1],'Description','Controller',... 'DefaultValue','LinearChoice','HeaderFile','Controller.h','DataScope',... 'Exported');
Specify the control expression for the Linear controller subsystem as V == Controller.LinearChoice and the control expression for the Nonlinear controller subsystem as V == Controller.NonLinearChoice.
set_param(lCtrlPath,"VariantControl","V == Controller.LinearChoice"); set_param(nlCtrlPath,"VariantControl","V == Controller.NonlinearChoice");
2. Set the value of V to Controller.NonlinearChoice.
V = Controller.NonlinearChoice;
3. In the C code tab, select Build > Generate code. Alternatively, enter this command in the Command Window.
slbuild(model);
### Searching for referenced models in model 'slexVariantSubsystems'. ### Total of 1 models to build. ### Starting build procedure for: slexVariantSubsystems ### Successful completion of build procedure for: slexVariantSubsystems Build Summary Top model targets: Model Build Reason Status Build Duration ==================================================================================================== slexVariantSubsystems Generated code was out of date. Code generated and compiled. 0h 0m 5.2578s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 5.6431s
The variable slex_V_VariantControlExpression stores the value of the variant control variable V, as the above example also shows.
cfile=fullfile(pwd, "slexVariantSubsystems_grt_rtw", "slexVariantSubsystems.c"); coder.example.extractLines(cfile, "/* Normal MATLAB Variables with Startup variant activation time */", "/* Block states (default storage) */", 1, 0);
/* Normal MATLAB Variables with Startup variant activation time */ Controller slex_V_VariantControlExpression = NonlinearChoice;
The LinearChoice and NonlinearChoice choices are defined as enumeration in the Controller.h file.
cfile=fullfile(pwd, "slexVariantSubsystems_grt_rtw", "Controller.h"); coder.example.extractLines(cfile, "#ifndef Controller_h_", "/* Controller_h_ */", 1, 1);
#ifndef Controller_h_
#define Controller_h_
#include "rtwtypes.h"
typedef enum {
LinearChoice = 0, /* Default value */
NonlinearChoice
} Controller;
Note
For variant blocks with the startup activation time, only enumerations that are defined using these techniques are supported:
Using the function
Simulink.defineIntEnumType.
By subclassing built-in integer data types
int8,int16,int32,uint8, oruint16, or by subclassingSimulink.IntEnumType. These enumerations are also supported when permanently stored in a Simulink data dictionary. See Enumerations in Data Dictionary.
See Also
Types of Variant Control Variables (Operands) in Variant Blocks