The S-Function Builder dialog box enables you to specify the attributes of an S-function to be built by an S-Function Builder block. To display the dialog box, double-click the S-Function Builder block icon or select the block and then select Open Block from the Edit menu on the model editor or the block's context menu.
The dialog box contains controls that let you enter information needed for the S-Function Builder block to build an S-function to your specifications. The controls are grouped into panes. See the following sections for information on the panes and the controls that they contain.
The following sections use the term target S-function to refer to the S-function specified by the S-Function Builder dialog box.
See Example: Modeling a Two-Input/Two-Output System for an example showing how to use the S-Function Builder to model a two-input/two-output discrete state-space system.
This pane displays the target S-function name and parameters and contains the following controls.
Specifies the name of the target S-function.
Specifies the target language for S-function. You can choose to generate your S-functions in C/C++, or you can inherit the model settings.
This table displays the parameters of the target S-function. Each row of the table corresponds to a parameter, and each column displays a property of the parameter as follows:
Name — Name of the parameter. Define and modify this property from the Parameters Pane.
Data type — Lists the data type of the parameter. Define and modify this property from the Parameters Pane.
Value — Specifies the value of the parameter. Enter a valid MATLAB® expression in this field.
Use this button to generate the C source code and executable MEX file from the information you entered in the S-Function Builder. If the button is labeled Build, the S-Function Builder generates the source code and executable MEX file. If the button is labeled Save, it generates only the C source code. Use the Save code only check box on the Build Info pane to toggle the functionality of this button.
Use the small button at the bottom-right of the Parameters/S-Function Name pane, to collapse and expand the bottom portion of the S-Function Builder dialog box.
This Port/Parameter pane on the left displays the ports and parameters that the dialog box specifies for the target S-function.
The pane contains a tree control whose top nodes correspond to the target S-function input ports, output ports, and parameters, respectively. Expanding the Input Ports, Output Ports, or Parameter node displays the input ports, output ports, or parameters, respectively, specified for the target S-function. Selecting any of the port or parameter nodes selects the corresponding entry on the corresponding port or parameter specification pane.
The Initialization pane allows you to specify basic features of the S-function, such as the width of its input and output ports and its sample time.
The S-Function Builder uses the information that you enter on this pane to generate the
mdlInitializeSizes
callback method. The
Simulink® engine invokes this method during the model initialization phase of the
simulation to obtain basic information about the S-function. (See Simulink Engine Interaction with C S-Functions for more
information on the model initialization phase.)
The Initialization pane contains the following fields.
Number of discrete states in the S-function.
Initial conditions of the discrete states in the S-function. You can enter the values
as a comma-separated list or as a vector (e.g., [0 1 2]
). The number of
initial conditions must equal the number of discrete states.
Number of continuous states in the S-function.
Initial conditions of the continuous states in the S-function. You can enter the
values as a comma-separated list or as a vector (e.g., [0 1 2]
). The
number of initial conditions must equal the number of continuous states.
Sample mode of the S-function. The sample mode determines the length of the interval between the times when the S-function updates its output. You can select one of the following options:
Inherited
The S-function inherits its sample time from the block connected to its input port.
Continuous
The block updates its outputs at each simulation step.
Discrete
The S-function updates its outputs at the rate specified in the Sample time value field of the S-Function Builder dialog box.
Scalar value indicating the interval between updates of the S-function outputs. This
field is enabled only if you select Discrete
as the Sample
mode.
The S-Function Builder does not currently support multiple-block sample times or a nonzero offset time.
PWorks
The number of data pointers used by the S-function. The PWorks
points to the memory over the lifecycle of the block. For example, you can declare and
initialize a pointer to a file or memory at the Start, and access it
in Outputs, Update, and
Derivatives panes, and deallocate it at the
Terminate pane. The code written in these panes are called by
mdlStart
, mdlOutputs
,
mdlUpdate
, mdlDerivatives
, and
mdlTerminate
. See the examples Moving Average with Start and
Terminate and Permutation using Cpp Classes.
Use of PWorks
affects the SimState compliance. If you declare
PWorks
, the use of SimState save and restore is not allowed.
Otherwise, the default SimState compliance setting,
USE_DEFAULT_SIM_STATE
, is used.
The Data Properties pane allows you to add ports and parameters to your S-function. The column of buttons to the left of the panes allows you to add, delete, or reorder ports or parameters, depending on the currently selected pane.
To add a port or a parameter, click the Add button.
To delete the currently selected port or parameter, click the Delete button.
To move the currently selected port or parameter up one position in the corresponding S-Function port or parameter list, click the Up button.
To move the currently selected port or parameter down one position in the corresponding S-function port or parameter list, click the Down button.
Array layout of your C/C++ code. You can select one of the options listed in the table.
Option | Array Layout of C/C++ Function | Action |
---|---|---|
Column-major | Column-major | The S-Function Builder block adds the SimStruct function |
Row-major | Row-major | The S-Function Builder block adds the SimStruct function During simulation, if your C/C++ code involves matrices or multidimensional inputs, outputs, or parameters, transposes are added to these S-function callback methods:
Simulink also applies the preceding transposes when running simulation in Accelerator and Rapid Accelerator modes. The S-function is not inlined by using TLC. Instead, the MEX S-function with transposes are compiled directly. |
Any | C/C++ function is not affected by array layout | The S-Function Builder block adds the SimStruct function |
This pane also contains tabbed panes that enable you to specify the attributes of the ports and parameters that you create. See:
The Input Ports pane allows you to inspect and modify the properties of the S-function input ports. The pane comprises an editable table that lists the properties of the input ports in the order in which the ports appear on the S-Function Builder block. Each row of the table corresponds to a port. Each entry in the row displays a property of the port as follows.
Name of the port. Edit this field to change the port name.
Lists the number of dimensions of the input signal accepted by the port. To display a
list of supported dimensions, click the adjacent button. To change the port
dimensionality, select a new value from the list. Specify 1-D
to size the signal dynamically, regardless of the actual dimensionality of the
signal.
Specifies the size of the first (or only) dimension of the input signal. Specify
-1
to size the signal dynamically.
Specifies the size of the second dimension of the input signal (only if the input port accepts 2-D signals).
For input signals with two dimensions, if the rows dimension is dynamically sized, the columns dimension must also be dynamically sized or set to 1. If the columns dimension is set to some other value, the S-function will compile, but any simulation containing this S-function will not run due to an invalid dimension specification.
Specifies whether the input port accepts real or complex-valued signals.
If the input signal to the S-Function Builder block is a bus, then use the drop-down
menu in the Bus
column to select
'on
'.
Step 2 of the Build S-Functions Automatically instructs you to
create a bus object, if your input signal is a bus. In the field provided in the
Bus Name
column, enter the bus name that you defined while creating
the inport bus object.
The Output Ports pane allows you to inspect and modify the properties of the S-function output ports. The pane consists of a table that lists the properties of the output ports in the order in which the ports appear on the S-Function block. Each row of the table corresponds to a port. Each entry in the row displays a property of the port as follows.
Name of the port. Edit this field to change the port name.
Lists the number of dimensions of signals output by the port. To display a list of
supported dimensions, click the adjacent button. To change the port dimensionality, select
a new value from the list. Specify 1-D
to size the signal
dynamically, regardless of the actual dimensionality of the signal.
Specifies the size of the first (or only) dimension of the output signal. Specify
-1
to size the signal dynamically.
Specifies the size of the second dimension of the output signal (only if the port outputs 2-D signals).
For output signals with two dimensions, if one of the dimensions is dynamically sized the other dimension must also be dynamically sized or set to 1. If the second dimension is set to some other value, the S-function will compile, but any simulation containing this S-function will not run due to an invalid dimension specification. In some cases, the calculations that determine the dimensions of dynamically sized output ports may be insufficient and both dimensions of the 2-D output signal may need to be hard coded.
Specifies whether the port outputs real or complex-valued signals.
If the output signal to the S-Function Builder block is a bus, then use the drop-down
menu in the Bus
column to select
'on
'.
Step 2 of the Build S-Functions Automatically instructs you to
create a bus object. In the field provided in the Bus Name
column,
enter the name that you defined while creating the outport bus object.
The Parameters pane allows you to inspect and modify the properties of the S-function parameters. The pane consists of a table that lists the properties of the S-function parameters. Each row of the table corresponds to a parameter. The order in which the parameters appear corresponds to the order in which the user must specify them in the S-function parameters field. Each entry in the row displays a property of the parameter as follows.
Name of the parameter. Edit this field to change the name.
Lists the data type of the parameter. Click the adjacent button to display a list of supported data types. To change the parameter data type, select a new type from the list.
Specifies whether the parameter has real or complex values.
This pane allows you to specify the data type attributes of the input and output ports of the target S-function. The pane contains a table listing the data type attributes of each of the S-functions ports. You can edit only some of the fields in the table. The other fields are grayed out. Each row corresponds to a port of the target S-function. Each column specifies an attribute of the corresponding port.
Name of the port. This field displays the name entered in the Input ports and Output ports panes. You cannot edit this field.
Data type of the port. Click the adjacent button to display a list of supported data types. To change the data type, select a different data type from the list.
The remaining fields on this pane are enabled only if the Data Type field specifies a fixed-point data type. See Specify Fixed-Point Data Types for more information.
The Libraries pane allows you to specify the location of external code files referenced by custom code that you enter in other panes of the S-Function Builder dialog box. It includes the following fields.
External library, object code, and source files referenced by custom code that you enter elsewhere on the S-Function Builder dialog box. List each file on a separate line. If the file resides in the current folder, you need specify only the file name. If the file resides in another folder, you must specify the full path of the file.
Alternatively, you can also use this field to specify search paths for libraries,
object files, header files, and source files. To do this, enter the tag
LIB_PATH
, INC_PATH
, or
SRC_PATH
, respectively, followed by the path name. You can make as many
entries of this kind as you need but each must reside on a separate line.
For example, consider an S-Function Builder project that resides at
d:\matlab6p5\work
and needs to link against the following
files:
c:\customfolder\customfunctions.lib
d:\matlab7\customobjs\userfunctions.obj
d:\externalsource\freesource.c
The following entries enable the S-Function Builder to find these files:
SRC_PATH d:\externalsource LIB_PATH $MATLABROOT\customobjs LIB_PATH c:\customfolder customfunctions.lib userfunctions.obj freesource.c
As this example illustrates, you can use LIB_PATH
to specify both
object and library file paths. You can include the library name in the
LIB_PATH
declaration, however you must place the object file name on
a separate line. The tag $MATLABROOT
indicates a path relative to the
MATLAB installation. You include multiple LIB_PATH
entries on
separate lines. The paths are searched in the order specified.
You can also enter preprocessor (-D
) directives in this field, for
example,
-DDEBUG
Each directive must reside on a separate line.
Do not put quotation marks around the library path, even if the path name has spaces in it. If you add quotation marks, the compiler will not find the library.
Header files containing declarations of functions, variables, and macros referenced by
custom code that you enter elsewhere on the S-Function Builder dialog box. Specify each
file on a separate line as #include
statements. Use brackets to enclose
the names of standard C header files (e.g., #include <math.h>
).
Use quotation marks to enclose names of custom header files (e.g., #include
"myutils.h"
). If your S-function uses custom include files that do not reside
in the current folder, you must use the INC_PATH
tag in the
Library/Object/Source files field to set the include path for the
S-Function Builder to the directories containing the include files (see Library/Object/Source files).
Declarations of external functions not declared in the header files listed in the Includes field. Put each declaration on a separate line. The S-Function Builder includes the specified declarations in the S-function source file that it generates. This allows S-function code that computes the S-function states or outputs to invoke the external functions.
Use the Start pane to write code to allocate memory at the start of
simulation. The allocated is referenced by Pworks
for use throughout the
S-function.
Use the Outputs pane to enter code that computes the outputs of the S-function at each simulation time step. This pane contains the following fields.
Code for the mdlOutputs
function that computes the output of the
S-function at each time step (or sample time hit, in the case of a discrete S-function).
When generating the source code for the S-function, the S-Function Builder inserts the
code in this field in a wrapper function of the form
void sfun_Outputs_wrapper(const real_T *u, real_T *y, const real_T *xD, /* optional */ const real_T *xC, /* optional */ const real_T *param0, /* optional */ int_T p_width0 /* optional */ real_T *param1 /* optional */ int_t p_width1 /* optional */ int_T y_width, /* optional */ int_T u_width) /* optional */ { /* Your code inserted here */ }
where sfun
is the name of the S-function. The S-Function Builder
inserts a call to this wrapper function in the mdlOutputs
callback method that it generates for your S-function. The
Simulink engine invokes the mdlOutputs
method at each simulation
time step (or sample time step in the case of a discrete S-function) to compute the
S-function output. The mdlOutputs
method in turn invokes the wrapper
function containing your output code. Your output code then actually computes and returns
the S-function output.
The mdlOutputs
method passes some or all of the following arguments
to the outputs wrapper function.
Argument | Description |
---|---|
u0, u1, ... uN | Pointers to arrays containing the inputs to the S-function, where
N is the number of input ports specified on the
Input ports pane found on the Data
Properties pane. The names of the arguments that appear in the
outputs wrapper function are the same as the names found on the Input
ports pane. The width of each array is the same as the input width
specified for each input on the Input ports pane. If you
specified -1 as an input width, the width of the array is specified by the wrapper
function's u_width argument (see below). |
y0, y1, ... yN | Pointer to arrays containing the outputs of the S-function, where
N is the number of output ports specified on the
Output ports pane found on the Data
Properties pane. The names of the arguments that appear in the
outputs wrapper function are the same as the names found on the Output
ports pane. The width of each array is the same as the output width
specified for each output on the Output ports pane. If you
specified -1 as the output width, the width of the array is specified by the
wrapper function's y_width argument (see below). Use this array
to pass the outputs that your code computes back to the Simulink engine. |
xD | Pointer to an array containing the discrete states of the S-function. This argument appears only if you specified discrete states on the Initialization pane. At the first simulation time step, the discrete states have the initial values that you specified on the Initialization pane. At subsequent sample-time steps, the states are obtained from the values that the S-function computes at the preceding time step (see Discrete Update Pane for more information). |
xC | Pointer to an array containing the continuous states of the S-function. This argument appears only if you specified continuous states on the Initialization pane. At the first simulation time step, the continuous states have the initial values that you specified on the Initialization pane. At subsequent time steps, the states are obtained by numerically integrating the derivatives of the states at the preceding time step (see Continuous Derivatives Pane for more information). |
param0 , p_width0 ,
param1 , p_width1 , ...
paramN , p_widthN | param0 , param1 ,
...paramN are pointers to arrays containing the S-function
parameters, where N is the number of parameters specified on
the Parameters pane found on the Data
Properties pane. p_width0 ,
p_width1 , ...p_widthN are the widths of
the parameter arrays. If a parameter is a matrix, the width equals the product of
the dimensions of the arrays. For example, the width of a 3-by-2 matrix parameter
is 6. These arguments appear only if you specify parameters on the Data
Properties pane. |
y_width | Width of the array containing the S-function outputs. This argument appears
in the generated code only if you specified -1 as the width of the S-function
output. If the output is a matrix, y_width is the product of
the dimensions of the matrix. |
u_width | Width of the array containing the S-function inputs. This argument appears in
the generated code only if you specified -1 as the width of the S-function input.
If the input is a matrix, u_width is the product of the
dimensions of the matrix. |
These arguments permit you to compute the output of the block as a function of its inputs and, optionally, its states and parameters. The code that you enter in this field can invoke external functions declared in the header files or external declarations on the Libraries pane. This allows you to use existing code to compute the outputs of the S-function.
Select this check box if the current values of the S-function inputs are used to compute its outputs. The Simulink engine uses this information to detect algebraic loops created by directly or indirectly connecting the S-function output to the S-function input.
If the S-function has continuous states, use the Continuous
Derivatives pane to enter code required to compute the state derivatives. Enter
code for the mdlDerivatives
function to compute the derivatives of the
continuous states in the Code description field on this pane. When
generating code, the S-Function Builder takes the code in this pane and inserts it in a
wrapper function of the form:
void sfun_Derivatives_wrapper(const real_T *u, const real_T *y, real_T *dx, real_T *xC, const real_T *param0, /* optional */ int_T p_width0, /* optional */ real_T *param1,/* optional */ int_T p_width1, /* optional */ int_T y_width, /* optional */ int_T u_width) /* optional */ { /* Your code inserted here. */ }
where sfun
is the name of the S-function. The S-Function Builder
inserts a call to this wrapper function in the mdlDerivatives
callback method that it generates for the S-function. The
Simulink engine calls the mdlDerivatives
method at the end of each
time step to obtain the derivatives of the continuous states (see Simulink Engine Interaction with C S-Functions). The Simulink solver numerically integrates the derivatives to determine the continuous
states at the next time step. At the next time step, the engine passes the updated states
back to the mdlOutputs
method (see Outputs Pane).
The mdlDerivatives
callback method generated for the S-function
passes the following arguments to the derivatives wrapper function:
u
y
dx
xC
param0
, p_width0
, param1
,
p_width1
, ... paramN
,
p_widthN
y_width
u_width
The dx
argument is a pointer to an array whose width is the same as
the number of continuous derivatives specified on the Initialization
pane. Your code should use this array to return the values of the derivatives that it
computes. See Outputs Pane for the meanings and usage of the
other arguments. The arguments allow your code to compute derivatives as a function of the
S-function inputs, outputs, and, optionally, parameters. Your code can invoke external
functions declared on the Libraries pane.
If the S-function has discrete states, use the Discrete Update pane to enter code that computes at the current time step the values of the discrete states at the next time step.
Enter code for the mdlUpdate
function to compute the values of the
discrete states in the Code description field on this pane. When
generating code, the S-Function Builder takes the code in this pane and inserts it in a
wrapper function of the form
void sfun_Update_wrapper(const real_T *u, const real_T *y, real_T *xD, const real_T *param0, /* optional */ int_T p_width0, /* optional */ real_T *param1,/* optional */ int_T p_width1, /* optional */ int_T y_width, /* optional */ int_T u_width) /* optional */ { /* Your code inserted here. */ }
where sfun
is the name of the S-function. The S-Function Builder
inserts a call to this wrapper function in the mdlUpdate
callback method that it generates for the S-function. The
Simulink engine calls the mdlUpdate
method at the end of each time
step to obtain the values of the discrete states at the next time step (see Simulink Engine Interaction with C S-Functions). At the next time
step, the engine passes the updated states back to the mdlOutputs
method
(see Outputs Pane).
The mdlUpdates
callback method generated for the S-function passes
the following arguments to the updates wrapper function:
u
y
xD
param0
, p_width0
, param1
,
p_width1
, ... paramN
,
p_widthN
y_width
u_width
See Outputs Pane for the meanings and usage of these
arguments. Your code should use the xD
(discrete states) variable to
return the values of the discrete states that it computes. The arguments allow your code to
compute the discrete states as functions of the S-function inputs, outputs, and, optionally,
parameters. Your code can invoke external functions declared on the
Libraries pane.
Use the Terminate pane for writing the code to free up the memory
allocated at the Start pane. Memory referenced by
PWorks
can also be seen by Terminate, and should
be deallocated here.
Use the Build Info pane to specify options for building the S-function MEX file. This pane contains the following fields.
Displays information as the S-Function Builder is generating the C source and executable files.
Log each build step in the Compilation diagnostics field.
Include debug information in the generated MEX file.
Make S-Function compatible with model coverage. For more information, see Coverage for Custom C/C++ Code in Simulink Models (Simulink Coverage) in Simulink Coverage™ documentation.
Selecting this option allows you to generate a TLC file. You need to generate a TLC file if you are running your model in Rapid Accelerator mode or generating Simulink Coder™ code from your model. Also, while it is not necessary for Accelerator mode simulations, the TLC file will generate code for the S-function and thus makes your model run faster in Accelerator mode.
Do not build a MEX file from the generated source code.
Makes the SimStruct
(S
) accessible to the
wrapper functions that S-Function Builder generates. This enables you to use the
SimStruct
macros and functions with your code in the
Outputs, Continuous Derivatives, and
Discrete Updates panes. For example, with this option enabled, you
can use macros such as ssGetT
in code that computes the
S-function outputs:
double t = ssGetT(S); if(t < 2 ) { y0[0] = u0[0]; } else { y0[0]= 0.0; }
Click this button to include additional TLC methods in the TLC file for your S-function. Check the methods you want to add and click the Close button to include the methods in your TLC file. For more information, see Block Target File Methods (Simulink Coder).
The example sfbuilder_example
shows how to use the S-Function Builder to model a
two-input/two-output discrete state-space system with two states. In the example, the
state-space matrices are parameters to the S-function and the S-function input and output
are vectors. You can find a manually written version of the S-function in dsfunc.c
.
You need to build the S-function before running the example model. To build the S-function, double-click on the S-Function Builder block in the model and click Build on the S-Function Builder dialog box that opens.
The Initialization pane specifies the number of discrete states and their initial conditions, as well as sets the sample time of the S-function. This example contains two discrete states, each initialized to 1, and a discrete sample mode with a sample time of 1.
The Data Properties pane specifies the dimensions of the S-function input and output, as well as initializes the state-space matrices.
The Input ports pane defines the one S-function input port as a 1-D vector with two rows.
The Output ports pane similarly defines the one S-function output port as a 1-D vector with two rows.
The Parameters pane defines four parameters, one for each of the four state-space matrices.
The S-function parameters pane at the top of the S-Function Builder contains the actual values for the state-space matrices, entered as MATLAB expressions. In this example, each state-space parameter is a two-by-two matrix. Alternatively, you can store the state-space matrices in variables in the MATLAB workspace and enter the variable names into the Value field for each parameter.
The Outputs pane calculates the S-function output as a function
of the input and state vectors and the state-space matrices. In the outputs code,
reference S-function parameters using the parameter names defined on the Data
Properties — Parameters pane. Index into 2-D
matrices using a scalar index, keeping in mind that S-functions use zero-based indexing.
For example, to access the element C(2,1)
in the S-function parameter
C
, use C[1]
in the S-function code.
The Outputs pane also selects the Inputs are needed in
the output function (direct feedthrough) option since this state-space model
has a nonzero D
matrix.
The Discrete Update pane updates the discrete states. As with the
outputs code, use the S-function parameter names and index into 2-D matrices using a
scalar index, keeping in mind that S-functions use zero-based indexing. For example, to
access the element A(2,1)
in the S-function parameter
A
, use A[1]
in the S-function code. The variable
xD
stores the final values of the discrete states.
Click the Build button on the S-Function Builder to create an
executable for this S-function. You can now run the model and compare the output to the
original discrete state-space S-function contained in sfcndemo_dsfunc
.