Main Content

Use Variant Subsystem Blocks with Conditionally Executed Subsystems

You can use conditionally executed subsystems that use control input ports such as Enabled, Triggered, Reset, and the Function-Call subsystems as variant choices within the Variant Subsystem block. For more information on conditionally executed systems, see Conditionally Executed Subsystems Overview.

Note

When the Variant activation time parameter of the Variant Subsystem block is set to code compile, the type of control port blocks in all the variant choices must be same. For example, you cannot use Enabled Subsystem and Function-Call Subsystem blocks as choices within a Variant Subsystem block that has code compile activation time.

The control input ports on the variant choice blocks and the corresponding input port on the parent Variant Subsystem block must have the same name.

Create a Variant Subsystem with Enabled Subsystem as Choice

Consider this model with a Variant Subsystem block named Controller and two Enabled Subsystem blocks, Linear and Nonlinear, as variant choices. The variant conditions on the Linear and Nonlinear blocks are VSSMODE==0 and VSSMODE==1, respectively. If you use an Enabled Subsystem block for the Linear choice, then the Nonlinear choice must also be an Enabled Subsystem.

When you generate code from this model, the Linear and Nonlinear choices are guarded by the corresponding variant conditions.

step() {
#if VSSMODE==0
// code for Linear choice
.......
#elif VSSMODE==1
// code for Nonlinear choice
.......
#endif

Use Variant Subsystem Block to Create an Export-Function Model

Export-function models are Simulink® models that generate code for independent functions that can be integrated with an external environment and scheduler. You can use a Variant Subsystem block with Function-Call Subsystem blocks as variant choices to create an export-function model. For more information on export-function models, see Export-Function Models Overview.

Consider a model containing a Variant Subsystem block named VariantFcnCall with two Function-Call Subsystem blocks, Linear and Nonlinear, as variant choices. The variant conditions set on Linear and Nonlinear choices are VSS_MODE==0 and VSS_MODE==1, respectively. The VariantFcnCallblock has a root level function-call inport block, fcn, and the same name is given to the control ports on the Linear and Nonlinear choice blocks. The Variant activation time parameter of VariantFcnCall is set to code compile.

You can also have a similar modeling pattern with a multi-point entry function using Model blocks.

In this example, the inputs fcln1, fcln2, and fcln3 are routed through a Variant Subsystem block, Model, that uses Model blocks as variant choices.

Code Generation for Export-Function Model

When you generate code from this model, the definition of the export function, fcn, contains the C preprocessor conditionals #if and #endif. The code for Linear and Nonlinear choices are guarded by the corresponding variant conditions. For more information on configuring the model to generate code, see Prepare Variant-Containing Model for Code Generation.

void fcn(void)
{
/* RootInportFunctionCallGenerator: '<Root>/RootFcnCall_InsertedFor_fcn_at_outport_1' */
#if VSSMODE == 0

    rtDWork.Linear.DiscreteFilter = rtU.In1 - 0.5 *
    rtDWork.Linear.DiscreteFilter_states;
    rtDWork.Linear.DiscreteFilter_states = rtDWork.Linear.DiscreteFilter;
  
#endif                                 /* VSSMODE == 0 */

#if VSSMODE == 1

    rtDWork.Nonlinear.DiscreteFilter = look1_binlxpw(rtU.In1,
    rtCP_LookupTable_bp01Data, rtCP_LookupTable_tableData, 4U) - 0.5 *
    rtDWork.Nonlinear.DiscreteFilter_states;
    rtDWork.Nonlinear.DiscreteFilter_states = rtDWork.Nonlinear.DiscreteFilter;
 
#endif                                 /* VSSMODE == 1 */
  
#if VSSMODE == 0
 
    rtY.Out1 = rtDWork.Linear.DiscreteFilter;

#endif                                 /* VSSMODE == 0 */
  
#if VSSMODE == 1
  
   rtY.Out1 = rtDWork.Nonlinear.DiscreteFilter;

#endif                                 /* VSSMODE == 1 */
 
}

Guard Export Function Definition in Generated Code

To guard the whole definition of the export function, fcn, using a variant condition, use a Variant Source block as shown in this example.

Guard the definition of an export function using a Variant Source block

In the generated code, the definition of the export function, fcn(), is guarded with A==1.

#if A == 1
void fcn(void)
{
…..
}
#endif

This function can be referred using a code snippet similar to this one.

…..
#if A==1
fcn()
#endif
……

Propagate Variant Conditions from Variant Subsystem Blocks to Conditional Subsystems

When you propagate a variant condition to a conditional subsystem, the same condition is set to all ports.

Consider this model. The Variant Subsystem block, VariantFcnCall, has conditional subsystem blocks as choices. The inport fcn on VariantFcnCall corresponds to the control input ports on the variant choice blocks. A single-input, single-output Variant Source block with the condition A==1 is connected to the fcn port. The VariantFcnCall block gets the variant condition of the signal connected to the fcn port. The condition assigned to the block then propagates to the blocks connected to its input and output ports. When you simulate this model after setting A=1, the variant condition A==1 propagates to the VariantFcnCall block and to the In1 and Out1 blocks connected to it, as shown in the Variant Conditions Legend.

Limitations

These conditions are not supported when using conditionally executed systems as variant choices within a Variant Subsystem block:

  • Action Port blocks in the variant choices.

  • Iterator Port blocks in the variant choices of a Variant Subsystem with Variant activation time set to code compile.

  • Configuring a model as an AUTOSAR component with runnable as a variant subsystem choice.

  • Initialize Function, Reset Function, Terminate Function, and Simulink Function blocks.

    Note

    Initialize and Terminate event ports are always unconditional because they control both the model default and block-specific initialize and terminate events of the referenced model. If you define an Initialize function block in the referenced model, it corresponds to an explicit initialize event.

Related Topics