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 befcn
.
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");