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 are constructed in Simulink by building a model whose 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. You can test these functions in all simulation modes, by providing model inputs through the root-level Inport blocks or by referencing this model in a top model to invoke the function-calls. This is subject to the guidelines described in Requirements for Export-Function Models.
The figure below shows an export-function model and the resulting generated functions.
To set up a model to export functions, you must meet a set of requirements that pertain to ensuring that the executable components of the model are made up exclusively of function-call blocks. The model must conform to the requirements listed below.
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 the referenced function-call
model's parameter Configuration Parameters > Solver > Tasking and sample time
options > Periodic sample time constraint is set to
Ensure sample time independent.
Inport and Outport blocks
Blocks with constant sample time (including blocks that resolve to constant sample time)
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 above.)
Blocks inside function-call subsystems must support code generation. These blocks must not use absolute time or elapsed time unless you specify a discrete sample time on the model's 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.
Note: Two or more function-call root-level Inport blocks must be driven by the same sample time in the top model if any of the following conditions are met.
When the sample time is specified on function-call root-level Inport blocks, the function will be executed periodically at that rate. Thus, periodic function-call run-time checks apply if this model is used as a reference model in normal simulation mode.
When using periodic sample time, the model configuration parameter Fixed-step
size (fundamental sample time) cannot be set to
The periodic sample time of the Inport block must be an integer multiple
of the model sample time.
If an Inport block has periodic sample time specified, then
its source block in the top model must also have the same sample time.
Function-call subsystems driven by these periodic function-call root-level
Inport blocks must set their function-call trigger block's Sample
time type parameter set to
Periodic and Sample
time set to
-1 (inherited) or the sample
time of the function-call root-level Inport block. Periodic sample
time function-call subsystems can contain blocks that use elapsed
time (e.g. Discrete-Time Integrator) and also blocks that use
absolute time (e.g. Digital Clock).
You can display the sorted execution order to interpret simulation
results. This has no impact on generated code. To display the sorted
execution order, select Display > Blocks > Sorted Execution Order. In the example below, 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:
Sample time (if distinct, non-inherited sample times)
When two blocks have different non-inherited sample times, the block with the faster rate executes first. Otherwise, the block with the lower priority number, if specified, executes first. If the Priority parameter is equal, blocks with the lower port number execute first. The following example shows how relative execution order is calculated.
Determine Relative Execution Order
Suppose an export function model has five root-level function-call 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 non-inherited), Priority parameter, and port number, in order.
|Root-level function-call Inport||A||B||C||D||E|
Look at blocks A and B. Notice that A has an inherited sample time (-1), which means that Simulink cannot compare the sample times. Because A has a lower priority number than B, it executes first.
Using the same logic, A and E execute before B, C, and D. A executes before E because it has a lower priority number.
This same logic determines the order of the remaining blocks (B, C, and D). C and D have distinct, non-inherited sample times, and the sample time for D is smaller (faster), so it executes before block C. D executes before B for the same reason.
Next, compare B and C. Because they have the same non-inherited sample time, Simulink looks at their block priority numbers, which are also the same. Simulink next looks at the port numbers. The port number for C (3) is smaller than B (4), and therefore C executes before B.
The relative execution order of these Inport blocks is, then, A, E, D, C, and B.
If the export-function model is referenced by a top model, there are restrictions on the order of specifying function-calls. These restrictions ensure consistency with standalone simulation results.
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.
In the top model, the same function-call initiator must output function-calls originating within the same sample time. Thus, you cannot use two function-call initiators with the same sample time.
Simulink displays an errors 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 correctly 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 below, 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, an annotation of ZOH is added next to In1. Similarly, FCSS2 (F2) executes after FCSS3 (F1). Hence, Simulink adds an annotation of 1/z next to In3 of subsystem FCSS3 (F1). Port In2 inputs signals from both FCSS1 (F0) and FCSS2 (F2). Hence, it has an annotation Mixed next to it.
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 must be of data type 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, you must repeat the time value accordingly. For example, to
specify three events at t = 1 and two events at t = 9, then you must
list 1 three times and 9 twice in your time vector i.e.,
= [1 1 1 9 9]'.
The table corresponding to normal data input port can be of any other supported format as described in Enable Data Import.
Follow the steps below to input data into a standalone export-function model via the Model Configuration Parameters dialog box.
Select Simulation > Configuration Parameters > Data Import/Export.
Select the Input parameter.
Enter the data as t, tu in the Data Import/Export pane:
Here, t is a column vector containing the times of events for the Inport block fcIn1 while tu is a table of input values versus time for Inport block In2.
If the function-call root-level Inport block has a discrete
sample time specified, use an empty matrix (
for the time vector. The function-call subsystem will execute at every
sample time hit of the root-level Inport block triggering it.
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 the behavior of the target environment, giving inputs to the exported functions. 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 preempting function-calls.
Multiple function-call initiators having distinct sample times: You can use Simulink scheduling for simulation in this case, which is especially useful when Simulink's rate monotonic scheduling behavior 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:
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.
A similar feature to export-function models is available since R2011a for models with asynchronous function-call inputs. These models are used primarily in the Simulink environment, where generated functions are called by the Simulink scheduler. Since the generated asynchronous function-call entry-points will be called by Simulink scheduler, the model can only be used as a referenced model for code generation. In contrast, the workflow for export-function models involves code generation of functions in standalone models.
|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 modes and standalone simulation in Normal, Accelerator, and Rapid Accelerator modes.|
|Code generation support||Top-model and standalone code generation is supported.||Top-model code generation is supported. Standalone code generation is not supported.|