Simulink provides the capability to export functions from Simulink® models that are invoked by controlling logic that is outside the model. Such models are called export-function models, and their functional blocks are made up exclusively of function-call subsystems, function-call model blocks or other export-function models. These blocks are invoked using function-call triggers passed via root-level Inport blocks. Execute these functions by providing model inputs through root-level Inport blocks or by referencing this model in a top model to invoke the function-calls. The execution of these functions is subject to the guidelines described in Requirements for Export-Function Models.
The figure shows an export-function model and the resulting generated functions.
To set up a model to export functions, first meet these requirements. These requirements ensure that the executable components of the model are made up only of function-call blocks.
The model solver must be a fixed-step discrete solver.
Configure each root-level Inport block triggering a function-call subsystem to output a function-call trigger. These Inport blocks cannot be connected to an Asynchronous Task Specification block.
Export-function models generate functions to be integrated with an external environment. Simulink does not generate a step function or a terminate function, and all blocks in these models must be executed in a function-call context. Thus, the model must contain only the following blocks at root level:
Function-call blocks, such as Function-Call
Subsystem, S-functions, and Simulink
Function blocks. Function-call Model blocks can be placed
at the root-level only if their model parameter Configuration Parameters > Solver > Tasking and sample time options > Periodic
sample time constraint is set to
sample time independent.
Inport and Outport blocks
Blocks with a sample time of
Merge and Data Store Memory blocks
Virtual connection blocks (Function-Call Split, Mux, Demux, Bus Creator, Bus Selector, Signal Specification, and any virtual subsystem that contains any of the blocks listed.)
Blocks inside function-call subsystems must support code generation. These blocks can use absolute or elapsed time if they are inside a periodic function-call subsystem with a discrete sample time specified on the corresponding function-call root-level Inport block.
Data signals connected to root-level Inport and root-level Outport blocks cannot be a virtual bus.
Data logging and signal-viewer blocks, such as the Scope block, are not allowed at the root level and within the function-call blocks.
There are two blocks for each function-call subsystem in export-function models where you need to specify the sample time. These blocks are the function-call root-level Inport block and the Trigger block inside the function-call subsystem. The table shows how to specify these sample times.
Function-call root-level Inport
block with inherited sample time (
Function-call root-level Inport block with discrete sample time specified
Trigger block of
function-call subsystem has sample time type set
Configuration not allowed.
Set sample time of Trigger block to inherited
cannot set the model configuration parameter Fixed-step
size (fundamental sample time) to
Trigger block of
function-call subsystem has sample time type set
No sample time specification.
No sample time specification. The subsystem executes at the specified rate.
You cannot set the model configuration
parameter Fixed-step size (fundamental sample time) to
The blocks that output function-call signals to the function-call root-level Inport blocks of the export-function models are called function-call initiators. When a top model references an export-function model, the blocks that supply the function-call inputs to the referenced model are the function-call initiators in the top model.
Top model function-call initiators that drive function-call blocks in the referenced export-function model can have different sample times. You can also mux function-call initiator blocks with different sample times before feeding them to the referenced export-function model. In the Solver pane of the Configuration Parameters dialog box, when you clear the Treat each discrete rate as a separate task check box, function-call initiator blocks with smaller sample times execute first.
The sample time of function-call initiators must be an integer multiple of the sample time of the corresponding data inputs to the export-function model. The initiators must invoke a function-call subsystem in an export-function model at simulation times that are integer multiples of the sample time of the function-call root-level Inport block of the subsystem.
When you mux function-call initiator blocks in the top-level model, the function-call blocks they invoke do not receive the name of the initiator.
You can use the sample time of each export function call in your model to control the scheduling of triggers. In the following example, notice that the order of the function-call triggers are determined by the sample times of their corresponding export-function blocks.
In this example, the function calls are scheduled based on the
sample time specified on the function-call port. Based on the color-coded
onesecond (F0) executes every
steps while function
twoseconds (F1) executes every
You specify the sample time on the root-level function-call input ports.
Using the sample time, you can have more fine-grained control over how function-call triggers are scheduled in your model.
For standalone export-function models, the ordering rules for function calls are as follows:
Irrespective of the sample time, the block with the highest block sorting priority executes first, followed by blocks with decreasing sorting priorities. Two blocks with the same priority are not supported.
If two blocks do have the same priority, the block that specified the faster rate executes first.
If the rates of two blocks are also the same, the block with the lower port index runs first.
For example, consider three function calls with input
ports specified as follows:
A1 (Ts = 2),
(Ts = 3, Priority = 10),
A3 (Ts = 2, Priority =
The execution order in this case is
You can display the sorted execution order to interpret simulation
results. This display has no impact on generated code. To display
the sorted execution order, select Display > Blocks > Sorted Execution Order. In the following example, notice the sorted order for
both the function-call triggers. Based on sorted order display labels,
fcIn2 (F1) when both have a sample
hit at the same time step.
The referenced export-function model in the top model shows the local execution order of the Inport and Outport blocks in the model.
Simulink compares Inport block properties to determine their relative execution order. Simulink checks the block properties in this order:
Priority (lower priority executes first)
Sample time (smaller sample time executes first)
Port number (smaller port number executes first)
When two blocks have different values for the Priority parameter, the block with the lower priority executes first. If the Priority parameter is equal, the block with the faster rate executes first. If Priority and sample time are the same for both of the blocks, the block with the lower port number executes first. This example shows how relative execution order is calculated.
When the simulation mode of the top model is
Determine Relative Execution Order
Suppose that an export function model has five function-call root-level Inport blocks, A to E, with block properties as shown in the table. To determine their relative execution order, Simulink compares their sample times (if distinct and noninherited), Priority parameter, and port number, in order.
|function-call root-level Inport||A||B||C||D||E|
Block A has the lowest priority of all five blocks. A executes first.
Using the same logic, B and E execute after A but before C and
D. Since B and E have the same priority, Simulink compares their
sample time to determine execution order. E has a sample time of
which is smaller than
0.2, the sample time of B.
E executes before B.
C and D have the same priority and the same distinct, noninherited sample times. The port number for D (2) is smaller than C (3), D executes before C.
The relative execution order of these Inport blocks, then, is A, E, B, D, and C.
If a top model references an export-function model, there are restrictions on function-call subsystems within the export-function model. These restrictions ensure consistency with standalone simulation results.
In the top model, the same function-call initiator must output function-calls originating with the same sample time. You cannot use two function-call initiators with the same sample time. You cannot disable this restriction.
The function-call inputs from the top model must follow the execution order of the function-call Inport blocks in the referenced export-function model. You can disable this restriction.
The sample time of the function-call root-level Inport block
must be inherited (
-1) or match the sample time
of the function-call initiator block that drives it. If you disable
this restriction, the sample time of the function-call root-level Inport block
must be inherited (
-1) or an integer multiple of
the sample time of the function-call initiator block.
To disable the restrictions, clear the check box Model Configuration Parameters > Model Referencing > Enable strict scheduling checks for referenced export-function models.
An error appears if the top model calls the referenced model functions out of order at any time step. For information on sorted execution order, see Control and Display the Sorted Order.
You must know the timing of the data being transferred between function-call subsystems to understand and interpret simulation results.
To display which subsystem executes first during simulation, the signal lines are annotated with different symbols at the input ports of the subsystems:
ZOH indicates that all source function-call subsystems execute before the function-call block reading this signal.
1/z indicated that all source function-call subsystems execute after the function-call block reading this signal.
Mixed indicates that some source function-call subsystems execute before and some function-call subsystems execute after the function-call block reading this signal.
In the block diagram, notice the sorted execution order for each block. We can see that for the input port In1 of subsystems FCSS3 (F1), the source subsystem FCSS1 (F0) executes before FCSS3 (F1). Hence, a badge of ZOH is added next to In1. Similarly, FCSS2 (F2) executes after FCSS3 (F1). Hence, Simulink adds a badge of 1/z next to In3 of subsystem FCSS3 (F1). Port In2 inputs signals from both FCSS1 (F0) and FCSS2 (F2). Hence, it has a badge Mixed next to it.
You can latch Inport blocks in function-call subsystems to ensure data integrity. If your function-call subsystems have Inport blocks that are latched, then the root-level data Inport block of the export-function model is latched only if all the data Inport blocks it is feeding to are latched. For more information, see Latch input for feedback signals of function-call subsystem outputs.
When referencing an export function model or a model with asynchronous function-call inputs, the data input to the referenced model is latched if all function-call block inputs it feeds inside the referenced model are latched.
Note: Data transfer signals are unprotected in the generated code by default. You must prevent data corruption in these signals due to pre-emption in the target environment or implementing protection using custom storage classes.
The most common workflow is to test function-call behavior through simulation and generate the functions using standalone code generation.
When function-call sequencing is simple enough to be specified as a model input, standalone simulation is the preferred workflow. For a standalone simulation, create data sets for the function-call and data root-level Inport blocks. For more information on function-call inputs, see Specifying Function-Call Inputs.
You can also specify the execution order for function-call subsystems. For more information, see Execution Order for Function-Call Root-level Inport Blocks.
You can create data sets for the function-call and data root-level Inport blocks in Simulation > Model Configuration Parameters > Data Import/Export > Input.
For function-call inputs, specify a time-vector indicating when events occur.
The time vector data type must be double and monotonically increasing.
All time data must be integer multiples of the model sample time.
To specify multiple function-calls at a given time
step, repeat the time value accordingly. For example, to specify three
events at t = 1 and two events at t = 9, list 1 three times and 9
twice in your time vector,
t = [1 1 1 9 9]'.
The normal data input can use any other supported format as described in Forms of Input Data.
Consider the following export-function model with one function-call input port fcIn1 and one data input In2.
In the Configuration Parameters > Data Import/Export pane, set
the Input parameter to
t is a column vector containing the times
of events for the Inport block.
a table of input values versus time for the
The table describes how to specify the vector
Root-level Inport block
with inherited sample time (
Root-level Inport block with discrete sample time specified
Function-call subsystem trigger
port sample time type is
Use an empty matrix(
Function-call subsystem trigger
port sample time type is
Use a nondecreasing column vector. Each element in the column vector must be an integral multiple of the fundamental sample time of the model. The function-call subsystem executes at the times specified by the column vector.
If you specify an empty
Use a nondecreasing column vector. Each element in the column vector must be an integral multiple of discrete sample time of the function-call root-level Inport block. The function-call subsystem executes at the times specified by the column vector.
specify an empty matrix (
The more common simulation workflow of export-function models is by referencing export-function models. When function-call sequencing is too complicated to specify with data sets in a standalone simulation, create a harness top model to mimic target environment behavior. Use this top model to give inputs to the export-function model. There are two forms to mimic behavior of the scheduling environment:
Common function-call initiator, in which you fully control the scheduling process. Use Stateflow® or S-functions to create arbitrary call sequences.
Note: Simulink does not simulate pre-empting function-calls.
Multiple function-call initiators with distinct sample times: Use Simulink scheduling for simulation, which is useful when the rate monotonic scheduling behavior in Simulink is similar to the target OS behavior.
Note: When using export-function models in top-model simulations, do not change the enable/disable status of the model during the simulation. Enable it at the start of the simulation and use function-calls to call it.
For standalone code generation, specify an ERT code-generation
target, such as
ert.tlc, and select Code > C/C++ Code > Build Model to generate code.
In the generated code, each function-call root Inport generates
a void-void function. The function name for each function-call root Inport block
is the name of the output function-call signal of the block. If there
is no signal name, then the function name is derived from the name
of the root Inport block. Building the model generates
a model initialization function but does not generate a model step
function or an enable/disable function.
To customize the model initialize function name for the referenced export-function model, open the top model and complete these steps:
Select Model Configuration Parameters > Code Generation > Interface.
Click Configure Model Functions.
In the Model Interface dialog box, set Function
Model specific C prototypes and
Type the function name in the Initialize function name text box and click Apply.
Generate code again to see the new function name.
Nested export-function models provide an additional layer of organization for your model. The schematic below explains how the user may export functions at the vehicle level or the individual feature level.
Note: An export-function model cannot contain a model with asynchronous function-call inputs, but can contain function-call subsystems and function-call models. A model with asynchronous function-call inputs can contain an export-function model, function-call subsystem or a function-call model.
An export-function models capability is available for models with asynchronous function-call inputs. You use these models primarily in the Simulink environment where the Simulink scheduler calls generated functions.
|Export-Function Models||Models with Asynchronous Function-Call Inputs|
|Definition||These models have function-call root-level Inport blocks that are not connected to an Asynchronous Task Specification block. These Inport blocks trigger function-call subsystems or referenced models with function-call trigger inputs.||These models have function-call root-level Inport blocks connected to Asynchronous Task Specification blocks. These Inport blocks trigger function-call subsystems or referenced models with function-call trigger inputs.|
|Root-level blocks||Only blocks executing in a function-call context are allowed at the root level.||Blocks executing in a non-function-call context are also allowed.|
|Data transfer||Use data transfer indicators to interpret simulation results. Data transfer in export-function models is not protected by default in generated code. For more details, see Data Transfer Between Function-Call Subsystems.||Use Rate Transition blocks to protect data transferred between function-call subsystems running at different rates. For more information, see Rate Transition.|
|Simulation support||These models support standalone simulation and top-model simulation in all simulation modes.||These models support top-model simulation in all simulation modes and standalone simulation in normal, accelerator, and rapid accelerator modes.|
|Code generation support||Top-model and standalone code generation is supported.||Top-model and standalone code generation is supported.|