Compile Code Conditionally for All Values of Variant Parameters with Same and Different Dimensions - MATLAB & Simulink (original) (raw)

Main Content

This example shows how to generate a C code that contains all the active and inactive values of variant parameters. The values are enclosed in preprocessor conditionals #if and #elif that enables you to compile the code conditionally based on the condition that evaluates to true.

In this example, you will learn how to:

Overview of Variant Parameters

Variant parameters can have multiple values. Each value of the variant parameter is associated with a variant condition expression. During simulation, the value of the variant parameter associated with the condition that evaluates to true is the active value of that parameter. The value associated with the condition that evaluates to false is the inactive value of that variant parameter. For more information, see Use Variant Parameters to Reuse Block Parameters with Different Values.

In the generated code, the active and inactive values of the variant parameters are enclosed in C preprocessor conditionals #if and #elif. The preprocessor conditionals enable you to conditionally compile the code for a given active value. You generate the code only once. You can then choose the active choice of variant parameters by changing the value of the variant control variable before running the code. You do not need to regenerate the code for different variant parameter choices.

Prerequisite

Before you start this example, we recommend you complete Options to Represent Variant Parameters in Generated Code.

Explore the model

1. Open the model.

open_system('slexVariantParametersCC')

The model contains blocks that have variant parameters that are specified as Simulink.VariantVariable objects. The objects are defined in the slexVariantParameterCCData.m file.

2. Open the slexVariantParameterData.m. Observe these settings in the file:

Set Active Choice of Variant Parameters

1. On the Simulink® toolstrip, click Run. During simulation, VCtrl==1 evaluates to true. All the values associated with VCtrl==1 are assigned to the corresponding variant variable objects and, subsequently, to the variant parameters that use these objects. For example, when VCtrl==1 evaluates to true, the value of MAX_LIFT is set to 10. As the Constant parameter of the Constant1 block is set to MAX_LIFT, the value of the Constant parameter is also set to 10.

2. To change the active values, change the value of VCtrl to 2, then simulate the model again.

During simulation, all the values associated with VCtrl==2 are assigned to the variant variable objects, and those values are then assigned to the variant parameters using those objects.

Generate Code Using Embedded Coder

To generate code for variant parameters that have values with different dimensions, use Embedded Coder.

Before you generate code from the model, make sure that you have write permission in your current folder. To generate code, in the Apps gallery of the model toolstrip, click Embedded Coder. On the C Code tab, click Build. For more information, see Generate Code Using Embedded Coder.

Review Inline and Tunable Parameters in Generated Code

1. In the C Code tab, select Open Report.

2. Select the slexVariantParametersCC_types.h file from the Generated Code pane of the report. This file defines the value of the variant control variable VCtrl as 1. The variant control variable determines the active value of variant parameters.

#ifndef VCtrl #define VCtrl 1 #endif

3. Select the slexVariantParametersCC_private.h file. This file includes macros (#define) corresponding to all the values of the variant parameters with default storage class Auto. The active values of variant parameters MAX_LIFT and SLIDER_POS are enclosed in the C preprocessor conditional statement (#if) on the macros rtCP_Constant_MAX_LIFT and rtCP_Constant1_SLIDER_POS.

Note: If the variant parameter has a default value specified using the (default) variant condition, the value is assigned in the #else condition in the code.

#if VCtrl == 1 || VCtrl == 2 /* Variable: MAX_LIFT

#if VCtrl == 1 #define rtCP_Constant_MAX_LIFT (10.0) #elif VCtrl == 2 #define rtCP_Constant_MAX_LIFT (20.0) #endif #endif

#if VCtrl == 1 || VCtrl == 2 /* Variable: SLIDER_POS

#if VCtrl == 1 #define rtCP_Constant1_SLIDER_POS (0.0) #elif VCtrl == 2 #define rtCP_Constant1_SLIDER_POS (0.5) #endif #endif

4. Select the slexVariantParametersCC.h file. This file includes symbolic names for all the values of the variant parameters with storage class set to ExportGlobal. The variables are defined as extern variables.

/* Exported Global Parameters #if VCtrl == 1 || VCtrl == 2 extern real_T T1Break[T1Break_dim0]; /* Variable: T1Break * Referenced by:'/1D Lookup' */ #endif

#if VCtrl == 1 || VCtrl == 2 extern real_T T1Data[T1Data_dim0]; /* Variable: T1Data * Referenced by:'/1D Lookup' */ #endif

#if VCtrl == 1 || VCtrl == 2 extern real_T T2Break[3]; /* Variable: T2Break * Referenced by:'/2D Lookup' */ #endif

#if VCtrl == 1 || VCtrl == 2 extern real_T T2Data[9]; /* Variable: T2Data * Referenced by:'/2D Lookup' */ #endif

5. Select the slexVariantParametersCC.c file. All the values of variant parameters are enclosed in C preprocessor conditional statements #if and #elif. When you compile this code, Simulink evaluates the preprocessor conditionals and compiles the code only for the active values of variant parameters. You can then specify a different value for VCtrl and recompile the same code for any other active values of variant parameters.

/* Exported block parameters */ #if VCtrl == 1

real_T T1Break[T1Break_dim0] = { -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 } ; /* Variable: T1Break * Referenced by: '/1D Lookup' */

real_T T1Data[T1Data_dim0] = { -0.99990920426259511, -0.999329299739067, -0.99505475368673046, -0.9640275800758169, -0.76159415595576485, 0.0, 0.76159415595576485, 0.9640275800758169, 0.99505475368673046, 0.999329299739067, 0.99990920426259511 } ; /* Variable: T1Data * Referenced by: '/1D Lookup' */

real_T T2Break[3] = { -10.0, 0.0, 10.0 } ; /* Variable: T2Break * Referenced by: '/2D Lookup' */

real_T T2Data[9] = { 4.0, 16.0, 10.0, 5.0, 19.0, 18.0, 6.0, 20.0, 23.0 } ; /* Variable: T2Data * Referenced by: '/2D Lookup' */

real_T T1Break[T1Break_dim0] = { -10.0, -9.0, -8.0, -7.0, -6.0, -5.0, -4.0, -3.0,-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 } ; /* Variable: T1Break * Referenced by: '/1D Lookup' */

real_T T1Data[T1Data_dim0] = { -0.99999999587769273, -0.999999969540041, -0.99999977492967584, -0.99999833694394469, -0.99998771165079559, -0.99990920426259511, -0.999329299739067, -0.99505475368673046, -0.9640275800758169, -0.76159415595576485, 0.0, 0.76159415595576485, 0.9640275800758169, 0.99505475368673046, 0.999329299739067, 0.99990920426259511, 0.99998771165079559, 0.99999833694394469, 0.99999977492967584, 0.999999969540041, 0.99999999587769273 } ; /* Variable: T1Data * Referenced by: '/1D Lookup' */

real_T T2Break[3] = { -20.0, 0.0, 20.0 }; /* Variable: T2Break * Referenced by: '/2D Lookup' */

real_T T2Data[9] = { 8.0, 32.0, 20.0, 10.0, 38.0, 36.0, 12.0, 40.0, 46.0 } ; /* Variable: T2Data * Referenced by: '/2D Lookup' */

In this file, calls to the step function of each variant are conditionally compiled. In the step function, the macros and symbol names of variant parameters are used to form the equation.

/* Model step function */

void slexVariantParameters_step(void) { slexVariantParametersCC_Y.Out1 = look2_binlx(rtCP_Constant_MAX_LIFT, look1_binlx(rtCP_Constant1_SLIDER_POS, T1Break, T1Data, T1Data_dim0

Review Dimension Symbol in Generated Code

Select the slexVariantParametersCC.c file from the Generated Code pane of the report. In this file, the dimensions of variant parameters T1Break and T1Data are represented as symbols T1Break_dim0 and T1Data_dim0 and are enclosed in C preprocessor conditional statements #if and #elif. When you compile this code, Simulink evaluates the preprocessor conditionals and preserves the code only for the active values of variant parameters. If you specify the value of VCtrl as 1, the condition VCtrl == 1 evaluates to true, and the values enclosed in V == 1 becomes active during code compilation. You can then specify a different value for VCtrl and recompile the same code for any other active values of T1Break and T1Data.

See Also

Topics