## Write Level-2 MATLAB S-Functions

### Setup Working Environment to Write Level-2 MATLAB S-Function

This example opens up a directory containing the following files required for this topic.

`msfuntmpl_basic.m`

`msfuntmpl.m`

`msfcn_unit_delay.m`

`msfcndemo_sfundsc2.slx`

### About Level-2 MATLAB S-Functions

The Level-2 MATLAB^{®} S-function
API allows you to use the MATLAB language to create custom blocks
with multiple input and output ports and capable of handling any type
of signal produced by a Simulink^{®} model, including matrix and
frame signals of any data type. The Level-2 MATLAB S-function
API corresponds closely to the API for creating C MEX S-functions.
Much of the documentation for creating C MEX S-functions applies also
to Level-2 MATLAB S-functions.
To avoid duplication, this section focuses on providing information
that is specific to writing Level-2 MATLAB S-functions.

A Level-2 MATLAB S-function is a MATLAB function that defines the properties and behavior of an instance of a Level-2 MATLAB S-Function block that references the MATLAB function in a Simulink model. The MATLAB function itself comprises a set of callback methods (see Level-2 MATLAB S-Function Callback Methods) that the Simulink engine invokes when updating or simulating the model. The callback methods perform the actual work of initializing and computing the outputs of the block defined by the S-function.

To facilitate these tasks, the engine passes a run-time object to the callback methods as an argument. The run-time object effectively serves as a MATLAB proxy for the S-Function block, allowing the callback methods to set and access the block properties during simulation or model updating.

### About Run-Time Objects

When the Simulink engine invokes a Level-2 MATLAB S-function callback method,
it passes an instance of the `Simulink.MSFcnRunTimeBlock`

class
to the method as an argument. This instance, known as the run-time
object for the S-Function block, serves the same purpose for Level-2 MATLAB S-function callback methods
as the `SimStruct`

structure serves for C MEX S-function
callback methods. The object enables the method to provide and obtain
information about various elements of the block ports, parameters,
states, and work vectors. The method does this by getting or setting
properties or invoking methods of the block run-time object. See the
documentation for the `Simulink.MSFcnRunTimeBlock`

class
for information on getting and setting run-time object properties
and invoking run-time object methods.

Run-time objects do not support MATLAB sparse matrices. For example, if
the variable `block`

is a run-time object, the following
line in a Level-2 MATLAB S-function
produces an error:

block.Outport(1).Data = speye(10);

where the `speye`

command forms a sparse identity
matrix.

**Note**

Other MATLAB programs
besides MATLAB S-functions
can use run-time objects to obtain information about a MATLAB S-function in a model that is
simulating. See Access Block Data During Simulation in *Using Simulink* for
more information.

### Level-2 MATLAB S-Function Template

Use the basic Level-2 MATLAB S-function template
`msfuntmpl_basic.m`

to get a head start on creating a new Level-2
MATLAB S-function. The template contains
skeleton implementations of the required callback methods defined by the Level-2 MATLAB S-function API. To write a more complicated
S-function, use the annotated template `msfuntmpl.m`

.

To create a MATLAB S-function, make a copy of the template and edit the copy as necessary to reflect the desired behavior of the S-function you are creating. The following two sections describe the contents of the MATLAB code template. The section Example of Writing a Level-2 MATLAB S-Function describes how to write a Level-2 MATLAB S-function that models a unit delay.

### Level-2 MATLAB S-Function Callback Methods

The Level-2 MATLAB S-function API defines the signatures and general purposes of the callback methods that constitute a Level-2 MATLAB S-function. The S-function itself provides the implementations of these callback methods. The implementations in turn determine the block attributes (e.g., ports, parameters, and states) and behavior (e.g., the block outputs as a function of time and the block inputs, states, and parameters). By creating an S-function with an appropriate set of callback methods, you can define a block type that meets the specific requirements of your application.

A Level-2 MATLAB S-function must include the following callback methods:

A

`setup`

function to initialize the basic S-function characteristicsAn

`Outputs`

function to calculate the S-function outputs

Your S-function can contain other methods, depending on the requirements of the block that the S-function defines. The methods defined by the Level-2 MATLAB S-function API generally correspond to similarly named methods defined by the C MEX S-function API. For information on when these methods are called during simulation, see Process View in Simulink Engine Interaction with C S-Functions.

The following table lists all the Level-2 MATLAB S-function callback methods and their C MEX counterparts.

### Using the `setup`

Method

The body of the `setup`

method in a Level-2 MATLAB S-function initializes the instance
of the corresponding Level-2 MATLAB S-Function
block. In this respect, the `setup`

method is similar
to the `mdlInitializeSizes`

and `mdlInitializeSampleTimes`

callback methods
implemented by C MEX S-functions. The `setup`

method
performs the following tasks:

Initializing the number of input and output ports of the block.

Setting attributes such as dimensions, data types, complexity, and sample times for these ports.

Specifying the block sample time. See Specify Sample Time in

*Using Simulink*for more information on how to specify valid sample times.Setting the number of S-function dialog parameters.

Registering S-function callback methods by passing the handles of local functions in the MATLAB S-function to the

`RegBlockMethod`

method of the S-Function block's run-time object. See the documentation for`Simulink.MSFcnRunTimeBlock`

for information on using the`RegBlockMethod`

method.

### Example of Writing a Level-2 MATLAB S-Function

The following steps illustrate how to write a simple Level-2 MATLAB S-function. When applicable, the steps include examples from the
S-function example `msfcn_unit_delay.m`

used in the model `msfcndemo_sfundsc2`

. All lines of code use the variable name
`block`

for the S-function run-time object.

Open MATLAB S-function template

`msfuntmpl_basic.m`

from the working folder. If you change the file name when you copy the file, change the function name in the`function`

line to the same name.Modify the

`setup`

method to initialize the S-function's attributes. For this example:Set the run-time object's

`NumInputPorts`

and`NumOutputPorts`

properties to`1`

in order to initialize one input port and one output port.Invoke the run-time object's SetPreCompInpPortInfoToDynamic and SetPreCompOutPortInfoToDynamic methods to indicate that the input and output ports inherit their compiled properties (dimensions, data type, complexity, and sampling mode) from the model.

Set the

`DirectFeedthrough`

property of the run-time object's`InputPort`

to`false`

in order to indicate the input port does not have direct feedthrough. Retain the default values for all other input and output port properties that are set in your copy of the template file. The values set for the`Dimensions`

,`DatatypeID`

, and`Complexity`

properties override the values inherited using the`SetPreCompInpPortInfoToDynamic`

and`SetPreCompOutPortInfoToDynamic`

methods.Set the run-time object's

`NumDialogPrms`

property to`1`

in order to initialize one S-function dialog parameter.Specify that the S-function has an inherited sample time by setting the value of the runtime object's

`SampleTimes`

property to`[-1 0]`

.Call the run-time object's

`RegBlockMethod`

method to register the following four callback methods used in this S-function.`PostPropagationSetup`

`InitializeConditions`

`Outputs`

`Update`

Remove any other registered callback methods from your copy of the template file. In the calls to

`RegBlockMethod`

, the first input argument is the name of the S-function API method and the second input argument is the function handle to the associated local function in the MATLAB S-function.

The following

`setup`

method from`msfcn_unit_delay.m`

performs the previous list of steps:function setup(block) %% Register a single dialog parameter block.NumDialogPrms = 1; %% Register number of input and output ports block.NumInputPorts = 1; block.NumOutputPorts = 1; %% Setup functional port properties to dynamically %% inherited. block.SetPreCompInpPortInfoToDynamic; block.SetPreCompOutPortInfoToDynamic; %% Hard-code certain port properties block.InputPort(1).Dimensions = 1; block.InputPort(1).DirectFeedthrough = false; block.OutputPort(1).Dimensions = 1; %% Set block sample time to [0.1 0] block.SampleTimes = [0.1 0]; %% Register methods block.RegBlockMethod('PostPropagationSetup',@DoPostPropSetup); block.RegBlockMethod('InitializeConditions',@InitConditions); block.RegBlockMethod('Outputs', @Output); block.RegBlockMethod('Update', @Update);

If your S-function needs continuous states, initialize the number of continuous states in the

`setup`

method using the run-time object's`NumContStates`

property. Do not initialize discrete states in the`setup`

method.Initialize the discrete states in the

`PostPropagationSetup`

method. A Level-2 MATLAB S-function stores discrete state information in a DWork vector. The default`PostPropagationSetup`

method in the template file suffices for this example.The following

`PostPropagationSetup`

method from`msfcn_unit_delay.m`

, named`DoPostPropSetup`

, initializes one DWork vector with the name`x0`

.function DoPostPropSetup(block) %% Setup Dwork block.NumDworks = 1; block.Dwork(1).Name = 'x0'; block.Dwork(1).Dimensions = 1; block.Dwork(1).DatatypeID = 0; block.Dwork(1).Complexity = 'Real'; block.Dwork(1).UsedAsDiscState = true;

If your S-function uses additional DWork vectors, initialize them in the

`PostPropagationSetup`

method, as well (see Using DWork Vectors in Level-2 MATLAB S-Functions).Initialize the values of discrete and continuous states or other DWork vectors in the

`InitializeConditions`

or`Start`

callback methods. Use the`Start`

callback method for values that are initialized once at the beginning of the simulation. Use the`InitializeConditions`

method for values that need to be reinitialized whenever an enabled subsystem containing the S-function is reenabled.For this example, use the

`InitializeConditions`

method to set the discrete state's initial condition to the value of the S-function's dialog parameter. For example, the`InitializeConditions`

method in`msfcn_unit_delay.m`

is:function InitConditions(block) %% Initialize Dwork block.Dwork(1).Data = block.DialogPrm(1).Data;

For S-functions with continuous states, use the

`ContStates`

run-time object method to initialize the continuous state data. For example:block.ContStates.Data(1) = 1.0;

Calculate the S-function's outputs in the

`Outputs`

callback method. For this example, set the output to the current value of the discrete state stored in the DWork vector.The

`Outputs`

method in`msfcn_unit_delay.m`

is:function Output(block) block.OutputPort(1).Data = block.Dwork(1).Data;

For an S-function with continuous states, calculate the state derivatives in the

`Derivatives`

callback method. Run-time objects store derivative data in their`Derivatives`

property. For example, the following line sets the first state derivative equal to the value of the first input signal.block.Derivatives.Data(1) = block.InputPort(1).Data;

This example does not use continuous states and, therefore, does not implement the

`Derivatives`

callback method.Update any discrete states in the

`Update`

callback method. For this example, set the value of the discrete state to the current value of the first input signal.The

`Update`

method in`msfcn_unit_delay.m`

is:function Update(block) block.Dwork(1).Data = block.InputPort(1).Data;

Perform any cleanup, such as clearing variables or memory, in the

`Terminate`

method. Unlike C MEX S-functions, Level-2 MATLAB S-function are not required to have a`Terminate`

method.

For information on additional callback methods, see Level-2 MATLAB S-Function Callback Methods.
For a list of run-time object properties, see the reference page for `Simulink.MSFcnRunTimeBlock`

and the
parent class `Simulink.RunTimeBlock`

.

### Instantiating a Level-2 MATLAB S-Function

To use a Level-2 MATLAB S-function in a model, copy
an instance of the Level-2 MATLAB S-Function block into the
model. Open the Block Parameters dialog box for the block and enter the name of the
MATLAB file that implements your S-function into
the **S-function name** field. If your S-function uses any additional
parameters, enter the parameter values as a comma-separated list in the Block Parameters
dialog box **Parameters** field.

### Operations for Variable-Size Signals

Following are modifications to the Level-2 MATLAB
S-functions template (`msfuntmpl_basic.m`

) and additional operations that allow you to use
variable-size signals.

function setup(block) % Register the properties of the output port block.OutputPort(1).DimensionsMode = 'Variable'; block.RegBlockMethod('SetInputPortDimensionsMode', @SetInputDimsMode); function DoPostPropSetup(block) %Register dependency rules to update current output size of output port a depending on %input ports b and c block.AddOutputDimsDependencyRules(a, [b c], @setOutputVarDims); %Configure output port b to have the same dimensions as input port a block.InputPortSameDimsAsOutputPort(a,b); %Configure DWork a to have its size reset when input size changes. block.DWorkRequireResetForSignalSize(a,true); function SetInputDimsMode(block, port, dm) % Set dimension mode block.InputPort(port).DimensionsMode = dm; block.OutputPort(port).DimensionsMode = dm; function setOutputVarDims(block, opIdx, inputIdx) % Set current (run-time) dimensions of the output outDimsAfterReset = block.InputPort(inputIdx(1)).CurrentDimensions; block.OutputPort(opIdx).CurrentDimensions = outDimsAfterReset;

### Generating Code from a Level-2 MATLAB S-Function

Generating code for a model containing a Level-2 MATLAB S-function requires that you provide a corresponding Target Language Compiler (TLC) file. You do not need a TLC file to accelerate a model containing a Level-2 MATLAB S-function. The Simulink Accelerator™ software runs Level-2 MATLAB S-functions in interpreted mode. However, M-file S-functions do not work with accelerated mode if the M-file S-function is in a model reference. For more information on writing TLC files for MATLAB S-functions, see Inlining S-Functions (Simulink Coder) and Inline MATLAB File S-Functions (Simulink Coder).

### MATLAB S-Function Examples

The Level-2 MATLAB S-function
examples provide a set of self-documenting models that illustrate
the use of Level-2 MATLAB S-functions.
Enter `sfundemos`

at
the MATLAB command prompt to view the examples.

### MATLAB S-Function Limitations

Level-2 MATLAB S-functions do not support zero-crossing detection.

You cannot trigger a function-call subsystem from a Level-2 MATLAB S-function.

## See Also

Level-2 MATLAB S-Function | S-Function Builder | S-Function | MATLAB Function