Main Content

Propagate Variant Conditions to Control Execution of Conditional Subsystems

Conditional subsystems such as Enabled, Triggered, Reset, and Function-Call subsystems are nonvirtual subsystems that allow you to control its execution with external signals. You can control the execution by conditionally providing the signals to the conditional subsystems using variant blocks. The variant condition that propagates to the conditional subsystem stays on the boundary of the subsystem. All blocks inside inherit the condition from the subsystem. The same condition is set to all the ports of the subsystem.

For more information on conditionally executed systems, see Conditionally Executed Subsystems Overview.

Variant Signals from Variant Source Outport to Function-Call Subsystem

This example shows how to conditionalize function-call signals to control the execution of a function-call subsystem using the Variant Source block. The variant condition that propagates to the Function-Call Subsystem block is set to all the ports of the subsystem.

Explore the Model

Consider the model slexVariantSourceFunctionCall.

The model contains a Variant Source block with the variant conditions A == 1 and A == 2 at its input ports. A is the variant control variable defined in the PreLoadFcn model callback. The variant conditions at the input and output ports of the Variant Source block determine the activation and deactivation of the blocks connected to it.

A Sine Wave block is connected to two MATLAB Function blocks, Filter Positive inputs and Filter Negative inputs. The Filter Positive inputs block generates a function call when the value of the Sine Wave block is positive. The Filter Negative inputs block generates a function call when the Sine Wave block value is 0 or negative. The Variant Source block receives these function-call signals at its input ports. The output port of the Variant Source block is connected to a Function-Call Subsystem block named Counter. The subsystem is triggered when A == 1 and the Sine Wave block outputs positive values, and when A == 2 and the Sine Wave block outputs 0 or negative values.

The Output function call parameter on the Variant Source1 block is set to on. This option enables the block to receive and output the function-call signals.

open_system("slexVariantSourceFunctionCall");

Simulate the Model

When you simulate the model, the logical OR of variant conditions A == 1 and A == 2 propagates to the Counter subsystem and all its ports to determine the active and inactive variant choices.

  • When A == 1, Filter Positive inputs is active.

  • When A == 2, Filter Negative inputs is active.

In both cases, the count value in the Counter subsystem is incremented. If A ~= 1 and A ~= 2, then Counter does not execute because the Sine Wave block is inactive.

sim("slexVariantSourceFunctionCall")

To explore how the variant conditions propagate in other conditional subsystems such as enabled subsystems, simulate the slexVariantControlPorts model and observe the results.

Note

If the function-call subsystem is placed inside a virtual grouped subsystem, the variant condition triggering the function-call subsystem must match the corresponding condition on the input of the higher-level subsystem block.

Variant Signals from Variant Subsystem Inport to Function-Call Subsystems

This example shows how to include multiple implementations of a Function-Call Subsystem block as variant choices in a Variant Subsystem block and execute them one at a time. The variant condition that propagates to the function-call subsystem is set to all the ports of the subsystem. When you use conditionally executed subsystems as variant choices:

  • The type of control port blocks in all the variant choices must be same as the Variant Subsystem block. For example, you cannot use enabled subsystem and function-call subsystem as choices within a Variant Subsystem block.

  • The control port on the Variant Subsystem block and the corresponding control ports on its variant choices must have the same name. For example, if the name of the control port on the Variant Subsystem is fcn, then the name of the corresponding control ports on all its variant choices must also be fcn.

Note

The properties set on the control ports that are inside the Variant Subsystem block are ignored during simulation and code generation.

Explore the Model

Consider the slexVariantSubsystemExportFunction model.

open_system("slexVariantSubsystemExportFunction")

The Variant Subsystem block VariantFcnCall has Function-Call Subsystem blocks as choices.

The inport fcn on VariantFcnCall corresponds to the control input ports on the variant choice blocks. During simulation, the VariantFcnCall block gets the variant condition of the signal connected to the fcn port. The variant condition assigned to the block then propagates to the blocks connected to its input and output ports. When you simulate the model, the logical OR of variant conditions from the variant choices, VSSMODE == 0 and VSSMODE == 1, propagates to the VariantFcnCall block and its ports. During simulation, if VSSMODE == 0 evaluates to true, the Linear block runs each time fcn receives a function-call event. If VSSMODE == 1 evaluates to true, the Nonlinear block runs each time fcn receives a function-call event.

sim("slexVariantSubsystemExportFunction");

To explore how the variant conditions from a Variant Subsystem block propagate to other underlying conditional subsystems such as enabled subsystems, simulate the slexVariantSubsystemEnabledChoices model and observe the results. For more information on enabled subsystems, see Using Enabled Subsystems.

Generate Code for Export-Function Model

Export-function models are Simulink® models that generate code for independent functions that you can integrate with an external environment or 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.

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. When you generate code from this model, the root-level function-call fcn block generates a void-void function. For information on how to generate code, see Generate Code Using Embedded Coder (Embedded Coder).

slbuild("slexVariantSubsystemExportFunction");
### Starting build procedure for: slexVariantSubsystemExportFunction
### Successful completion of build procedure for: slexVariantSubsystemExportFunction

Build Summary

Top model targets built:

Model                               Action                        Rebuild Reason                                    
====================================================================================================================
slexVariantSubsystemExportFunction  Code generated and compiled.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 17.084s

The function name is the name of the output signal from the block. If there is no signal name, then the function name is derived from the name of the block. In this example, the function name fcn is derived from the block name.

As the Variant activation time of VariantFcnCall is set to code compile, the definition of the function fcn contains the C preprocessor conditionals #if and #endif. The code for the Linear and Nonlinear choices are guarded by the corresponding variant conditions.

void fcn(void)
{
 #if VSSMODE == 0
 /* Outputs for Function Call SubSystem: '<S1>/Linear' */
 /* DiscreteFilter: '<S2>/Discrete Filter' incorporates:
 *  Inport: '<Root>/In1'
 */
    rtY.Out1 = rtU.In1 - 0.5 * rtDWork.DiscreteFilter_states_a;
 /* Update for DiscreteFilter: '<S2>/Discrete Filter' */
    rtDWork.DiscreteFilter_states_a = rtY.Out1;
/* End of Outputs for SubSystem: '<S1>/Linear' */
#elif VSSMODE == 1
/* Outputs for Function Call SubSystem: '<S1>/Nonlinear' */
/* DiscreteFilter: '<S2>/Discrete Filter' incorporates:
*  DiscreteFilter: '<S3>/Discrete Filter'
*  Inport: '<Root>/In1'
*  Lookup_n-D: '<S3>/Lookup Table'
*/
 rtY.Out1 = look1_binlxpw(rtU.In1, rtCP_LookupTable_bp01Data,
 rtCP_LookupTable_tableData, 4U) - 0.5 * rtDWork.DiscreteFilter_states;
/* Update for DiscreteFilter: '<S3>/Discrete Filter' */
 rtDWork.DiscreteFilter_states = rtY.Out1;
/* End of Outputs for SubSystem: '<S1>/Nonlinear' */
#endif
}

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 with the Variant activation time set to code compile as shown in this example. The function definition is not guarded for blocks with startup activation time.

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

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

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

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

Limitations

The following are not supported when you use conditionally executed systems as variant choices within a Variant Subsystem block:

  • Action Port blocks in the variant choices

  • Iterator subsystems as variant choices with the Variant activation time of the Variant Subsystem block set to code compile

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

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

To explore how to create export-function models for function-call subsystems connected to Variant Source blocks, simulate the slexVariantExportedFcn model and observe the results.

Variant Signals from Variant Subsystem Outport to Function-Call Subsystems

This example shows how to conditionalize the function-call signals to control the execution of a Function-Call Subsystem block using the Variant Subsystem block. The variant condition that propagates to the Function-Call Subsystem block is set to all the ports of the subsystem.

Explore the Model

Open the model slexVariantSubsystemFunctionCall.

The model contains a Variant Subsystem block with two Chart blocks, Chart1 and Chart2, as variant choices. The variant control variable A is defined in the PreLoadFcn model callback. The variant conditions on Chart1 and Chart2 are A == 1 and A == 2 respectively. A Pulse Generator block is connected to the Variant Subsystem block.

open_system("slexVariantSubsystemFunctionCall");

Chart1 and Chart2 are configured with port names that match the corresponding port names of the Variant Subsystem block.

open_system("slexVariantSubsystemFunctionCall/Variant Subsystem");

The Output function call parameter is selected on the Signal Attributes tab of the Block Parameters dialog box of the Outport block named activate(). This option allows the outport of the Counter subsystem to emit function-call signals.

Simulate the Model

When you simulate the model, the logical OR of variant conditions A == 1 and A == 2 propagates to the Counter subsystem and all its ports to determines the active and inactive variant choices.

  • When A == 1, Chart1 is active.

  • When A == 2, Chart2 is active.

The outport activate() gets function-call signal from the choices Chart1 and Chart2. When the Function-Call Subsystem block is triggered, there is a sine wave output at Out2.

sim("slexVariantSubsystemFunctionCall");

Related Topics