このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
Group Variant Parameter Values and Conditionally Switch Active Value Sets in Generated Code
This example shows how to group variant parameters with the same variant conditions into a structure in the generated code. You will learn to:
Use variant parameter banks to group variant parameters with
startupactivation time in code generated by Embedded Coder®.Specify code generation properties for variant parameter banks.
Overview of Variant Parameters
Variant parameters enable you to conditionally vary the values of block parameters in a Simulink® model. Use the Simulink.VariantVariable class to create a variant parameter object. A variant parameter object defines a set of values, referred to as choices, and variant condition expressions associated with each choice. During simulation, the choice associated with the variant condition that evaluates to true becomes the active value of the variant parameter.
To specify the variant conditions for a variant parameter, use a variant control variable of type Simulink.VariantControl. The Simulink.VariantControl object allows you to specify a variant activation time for the variant parameter. For example, in this MATLAB® code, VCtrl is a variant control with startup activation time. The variant parameter TABLE_DIM_0 has two choices, 10 and 20. For each choice, a variant condition is specified using VCtrl.
VCtrl = Simulink.VariantControl('Value',int32(1),'ActivationTime','startup'); TABLE_DIM_0 = Simulink.VariantVariable('Choices',{'VCtrl == 1',10,'VCtrl == 2',20});
The representation of variant parameters in the generated code depends on the ActivationTime of Simulink.VariantControl and the Specification property of the Simulink.VariantVariable object. Based on the variant activation time, Simulink determines whether to include only the active choice or both the active and inactive choices of the variant parameter in the code. The Specification property allows you to specify properties such as data type, dimensions, and storage class applicable to all the choices.
For more information on variant activation times, see Activate Variant During Different Stages of Simulation and Code Generation Workflow. For information on variant parameter code generation, see Options to Represent Variant Parameters in Generated Code (Embedded Coder).
Overview of Variant Parameter Banks
When you generate code for variant parameters with startup activation time, the values of variant parameters are enclosed in if and else if statements in the model_initialize function. This involves reading and copying all parameter values into the program memory. Also, when you define a custom storage class to define the variant parameter values in a separate definition file, only the active values of the parameters are present in the definition file. To improve the efficiency and readability of the generated code for variant parameters with startup activation time, you can use variant parameter banks.
Parameter banks help you to:
Group variant parameter values with the same variant conditions into a structure array.
Use a pointer switching mechanism to switch the set of active parameter values in the code based on variant conditions.
Customize code placement and specify the memory section to place the parameter values and the pointer variable in the compiled code.
A variant parameter bank is an object of type Simulink.VariantBank. To add a variant parameter to a variant parameter bank, set the Bank property of the Simulink.VariantVariable object to the name of the Simulink.VariantBank object. When you generate code, Simulink.VariantVariable objects that share the same Bank property become part of the same structure in the code.
You must specify a list of variant conditions for a parameter bank. These conditions must match the variant conditions of the variant parameters in this parameter bank, except any default variant choice specified for the variant parameters using the (default) keyword. For example, this MATLAB code creates a variant parameter bank.
LUTBank = Simulink.VariantBank(Name='LUTBpAndData',... Description='Lookup table breakpoint and data',... VariantConditions={'VCtrl == 1','VCtrl == 2'});
Alternatively, you can create variant parameter banks from Variant Manager. See Manage Variant Parameters Using Variant Manager.
Note: When using both Specification and Bank properties for a Simulink.VariantVariable object, the specification object must have storage class set to Auto and it must not use symbolic dimensions. For a variant parameter bank, use a Simulink.VariantBankCoderInfo object to specify code generation attributes.
Explore Example Model
1. Open the model slexVariantParameterBank.
model = "slexVariantParameterBank";
open_system(model);

The slexVariantParameterBank model contains blocks that use variant parameters. The variant parameters are defined as Simulink.VariantVariable objects in the slexVariantParameterBankData.m file.
The values of the Constant parameters of the two Constant blocks in the model are set to the variant parameter objects
SHIFT_VALUEandTABLE_DIM_0.
The Table data and Breakpoint sets of the n-D Lookup Table blocks are specified using the variant parameter objects
T1Break,T1Data,T2Break, andT2Data.
2. Open the file slexVariantParameterBankData.m. Observe these settings in the file:
VCtrlis defined as aSimulink.VariantControlobject. The value ofVCtrlis set to1, and its activation time is set tostartup. This object is used as a variant control variable to define the variant conditions for all the variant parameter objects. During simulation, the choices associated with the conditionVCtrl==1become active, and the choices associated withVCtrl==2become inactive.
LUTBankis defined as aSimulink.VariantBankobject. This variant parameter bank is used to group the variant parameter objectsT1Break,T1Data,T2Break, andT2Data. Hence,LUTBankhas the same set of variant conditions as these variant parameter objects. TheAllChoicesCoderInfoproperty of this variant parameter bank object is set toLUTAllChoicesCoderInfoand theActiveChoiceCoderInfoproperty is set toLUTActiveChoiceCoderInfo.
LUTAllChoicesCoderInfoandLUTActiveChoiceCoderInfoareSimulink.VariantBankCoderInfoobjects. TheLUTAllChoicesCoderInfoobject specifies code generation properties such as the header file, definition file, type qualifier, and#pragmadirectives for the structure array that representsLUTBankin the generated code. Similarly,LUTActiveChoiceCoderInfoallows you to specify these attributes separately for the pointer variable.
The
Bankproperty of the variant parameter objectsT1Break,T1Data,T2Break, andT2Datais set toLUTBank.
Generate Code
To generate code that uses variant parameter bank switching, use Embedded Coder. Before you generate code from the model, check whether you have write permission in your current folder. For more information, see Embedded Coder を使用したコード生成 (Embedded Coder).
slbuild(model)
### Searching for referenced models in model 'slexVariantParameterBank'. ### Total of 1 models to build. ### Starting build procedure for: slexVariantParameterBank ### Successful completion of build procedure for: slexVariantParameterBank Build Summary Top model targets: Model Build Reason Status Build Duration =========================================================================================================================== slexVariantParameterBank Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 24.866s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 27.181s
Review Generated Code
1. In the C Code tab, select Open Report. In the Code > Data Files section of the report, the header and definition files are named according to the properties of the objects LUTAllChoicesCoderInfo and LUTActiveChoiceCoderInfo.
2. Select the header file variantBank_lut_array_p.h. The file contains the type definition and data declarations of the variant parameter bank structure array.
The variant parameters that are part of the parameter bank LUTBank are grouped in the same structure. This structure is named LUTBpAndData, according to the Name property of the object LUTBank.
file = fullfile("slexVariantParameterBank_ert_rtw", ... "variantBank_lut_array_p.h"); coder.example.extractLines(file,"typedef struct {","} LUTBpAndData;",1,1)
typedef struct {
real_T T1Break[11]; /* Variable: T1Break
* Referenced by: '<Root>/1D Lookup'
*/
real_T T1Data[11]; /* Variable: T1Data
* Referenced by: '<Root>/1D Lookup'
*/
real_T T2Break[3]; /* Variable: T2Break
* Referenced by: '<Root>/2D Lookup'
*/
real_T T2Data[9]; /* Variable: T2Data
* Referenced by: '<Root>/2D Lookup'
*/
} LUTBpAndData;
A structure array named LUTBpAndData_ptr_impl of type LUTBpAndData is declared. The number of elements in the array depends on the number of variant conditions in the VariantConditions property of the parameter bank object LUTBank. These statements are guarded with the code specified in the PreStatement and PostStatement properties of the LUTActiveChoiceCoderInfo object. The type qualifier specified in the Qualifier property is applied to the declaration and definition of the array.
file = fullfile("slexVariantParameterBank_ert_rtw", ... "variantBank_lut_array_p.h"); coder.example.extractLines(file,"#pragma data_seg(.arrdata)","#endif",1,0)
#pragma data_seg(.arrdata) extern const LUTBpAndData LUTBpAndData_ptr_impl[2]; #pragma end
3. Select the definition file variantBank_lut_array_p.c. The file contains the definition of the structure array.
The LUTBpAndData_ptr_impl array contains the choices of the variant parameters, grouped by the variant conditions specified for the parameter bank.
file = fullfile("slexVariantParameterBank_ert_rtw", ... "variantBank_lut_array_p.c"); coder.example.extractLines(file,"#pragma data_seg(.arrdata)"," * File trailer for generated code.",1,0)
#pragma data_seg(.arrdata)
const LUTBpAndData LUTBpAndData_ptr_impl[2] = {
{
/* Variable: T1Break
* Referenced by: '<Root>/1D Lookup'
*/
{ -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 },
/* Variable: T1Data
* Referenced by: '<Root>/1D Lookup'
*/
{ -0.99990920426259511, -0.999329299739067, -0.99505475368673046,
-0.9640275800758169, -0.76159415595576485, 0.0, 0.76159415595576485,
0.9640275800758169, 0.99505475368673046, 0.999329299739067,
0.99990920426259511 },
/* Variable: T2Break
* Referenced by: '<Root>/2D Lookup'
*/
{ -10.0, 0.0, 10.0 },
/* Variable: T2Data
* Referenced by: '<Root>/2D Lookup'
*/
{ 4.0, 16.0, 10.0, 5.0, 19.0, 18.0, 6.0, 20.0, 23.0 }
}, {
/* Variable: T1Break
* Referenced by: '<Root>/1D Lookup'
*/
{ -10.0, -8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0 },
/* Variable: T1Data
* Referenced by: '<Root>/1D Lookup'
*/
{ -74.203210577788752, -27.28991719712775, -10.017874927409903,
-3.626860407847019, -1.1752011936438014, 0.0, 1.1752011936438014,
3.626860407847019, 10.017874927409903, 27.28991719712775,
74.203210577788752 },
/* Variable: T2Break
* Referenced by: '<Root>/2D Lookup'
*/
{ -20.0, 0.0, 20.0 },
/* Variable: T2Data
* Referenced by: '<Root>/2D Lookup'
*/
{ 6.0, 16.0, 12.0, 7.0, 19.0, 16.0, 8.0, 20.0, 20.0 }
}
};
#pragma end
/*
4. Similarly, inspect the variantBank_lut_ptr_p.h and variantBank_lut_ptr_p.c files that contain the declaration and definition of the pointer variable, as specified in the object LUTActiveChoiceCoderInfo.
file = fullfile("slexVariantParameterBank_ert_rtw", ... "variantBank_lut_ptr_p.h"); coder.example.extractLines(file,"#pragma data_seg(.ptrdata)","#endif",1,0)
#pragma data_seg(.ptrdata) extern const volatile LUTBpAndData *LUTBpAndData_ptr; #pragma end
file = fullfile("slexVariantParameterBank_ert_rtw", ... "variantBank_lut_ptr_p.c"); coder.example.extractLines(file,"#pragma data_seg(.ptrdata)"," * File trailer for generated code.",1,0)
#pragma data_seg(.ptrdata) const volatile LUTBpAndData *LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[0]; #pragma end /*
5. Select the slexVariantParameterBank.c file. The model_initialize function contains the code to switch the active variant choice based on variant conditions. For variant parameters that are part of a parameter bank, the pointer variable is used to access the active value set from the structure array based on variant conditions.
file = fullfile("slexVariantParameterBank_ert_rtw", ... "slexVariantParameterBank.c"); coder.example.extractLines(file,"/* Variant Parameters startup activation time */","slexVaria_startupVariantChecker();",0,0)
if (VCtrl == 1) {
LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[0U];
} else if (VCtrl == 2) {
LUTBpAndData_ptr = &LUTBpAndData_ptr_impl[1U];
}
/* Variant Parameters startup activation time */
if (VCtrl == 1) {
slexVariantParameterBank_P.SHIFT_VALUE = -18.0;
slexVariantParameterBank_P.TABLE_DIM_0 = 10.0;
} else if (VCtrl == 2) {
slexVariantParameterBank_P.SHIFT_VALUE = -16.0;
slexVariantParameterBank_P.TABLE_DIM_0 = 20.0;
}
参考
Simulink.VariantVariable | Simulink.VariantBank | Simulink.VariantBankCoderInfo