| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Real-Time Workshop |
| Contents | Index |
| Learn more about Real-Time Workshop |
You can use the following SimStruct macros in the mdlInitializeSizes method to specify the scope and reusability of the memory used for your S-function's input and output ports:
ssSetInputPortOptimOpts: Specify the scope and reusability of the memory allocated to an S-function input port
ssSetOutputPortOptimOpts: Specify the scope and reusability of the memory allocated to an S-function output port
ssSetInputPortOverWritable: Specify whether one of your S-function's input ports can be overwritten by one of its output ports
ssSetOutputPortOverwritesInputPort: Specify whether an output port can share its memory buffer with an input port
You declare an input or output as local or global, and indicate its reusability, by passing one of the following four options to the ssSetInputPortOptimOpts and ssSetOutputPortOptimOpts macros:
SS_NOT_REUSABLE_AND_GLOBAL: Indicates that the input and output ports are stored in separate memory locations in the global block input and output structure
SS_NOT_REUSABLE_AND_LOCAL: Indicates that the Real-Time Workshop software can declare individual local variables for the input and output ports
SS_REUSABLE_AND_LOCAL: Indicates that the Real-Time Workshop software can reuse a single local variable for these input and output ports
SS_REUSABLE_AND_GLOBAL: Indicates that these input and output ports are stored in a single element in the global block input and output structure
Note Marking an input or output port as a local variable does not guarantee the Real-Time Workshop code generator uses a local variable in the generated code. If your S-function accesses the inputs and outputs only in its mdlOutputs routine, the code generator declares the inputs and outputs as local variables. However, if the inputs and outputs are used elsewhere in the S-function, the code generator includes them in the global block input and output structure. |
The reusability setting indicates if the memory associated with an input or output port can be overwritten. To reuse input and output port memory:
Indicate the ports are reusable using either the SS_REUSABLE_AND_LOCAL or SS_REUSABLE_AND_GLOBAL option in the ssSetInputPortOptimOpts and ssSetOutputPortOptimOpts macros
Indicate the input port memory is overwritable using ssSetInputPortOverWritable
If your S-function has multiple input and output ports, use ssSetOutputPortOverwritesInputPort to indicate which output and input ports share memory
The following example shows how different scope and reusability settings effect the generated code. The following model contains an S-function block pointing to the C MEX S-function matlabroot/simulink/src/sfun_directlook.c, which models a direct 1-D lookup table.

The S-function's mdlInitializeSizes method declares the input port as reusable, local, and overwritable and the output port as reusable and local, as follows:
static void mdlInitializeSizes(SimStruct *S)
{
/* snip */
ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
ssSetInputPortOverWritable(S, 0, TRUE);
/* snip */
ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
/* snip */
}The generated code for this model stores the input and output signals in a single local variable rtb_SFunction, as shown in the following output function:
static void sl_directlook_output(int_T tid)
{
/* local block i/o variables */
real_T rtb_SFunction[2];
/* Sin: '<Root>/Sine Wave' */
rtb_SFunction[0] = sin(((real_T)sl_directlook_DWork.counter[0] +
sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[0] +
sl_directlook_P.SineWave_Bias;
rtb_SFunction[1] = sin(((real_T)sl_directlook_DWork.counter[1] +
sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[1] +
sl_directlook_P.SineWave_Bias;
/* S-Function Block: <Root>/S-Function */
{
const real_T *xData = &sl_directlook_P.SFunction_XData[0];
const real_T *yData = &sl_directlook_P.SFunction_YData [0];
real_T spacing = xData[1] - xData[0];
if (rtb_SFunction[0] <= xData[0] ) {
rtb_SFunction[0] = yData[0];
} else if (rtb_SFunction[0] >= yData[20] ) {
rtb_SFunction[0] = yData[20];
} else {
int_T idx = (int_T)( ( rtb_SFunction[0] - xData[0] ) / spacing );
rtb_SFunction[0] = yData[idx];
}
if (rtb_SFunction[1] <= xData[0] ) {
rtb_SFunction[1] = yData[0];
} else if (rtb_SFunction[1] >= yData[20] ) {
rtb_SFunction[1] = yData[20];
} else {
int_T idx = (int_T)( ( rtb_SFunction[1] - xData[0] ) / spacing );
rtb_SFunction[1] = yData[idx];
}
}
/* Outport: '<Root>/Out1' */
sl_directlook_Y.Out1[0] = rtb_SFunction[0];
sl_directlook_Y.Out1[1] = rtb_SFunction[1];
UNUSED_PARAMETER(tid);
}
The following table shows variations of the code generated for this model when using the generic real-time target (GRT). Each row explains a different setting for the scope and reusability of the S-function's input and output ports.
| Scope and reusability | S-function mdlInitializeSizes code | Generated code |
|---|---|---|
| Inputs: Local, reusable, overwritable Outputs: Local, reusable | ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL); ssSetInputPortOverWritable(S, 0, TRUE); ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL); | The model.c file
declares a local variable in the output function./* local block i/o variables */ real_T rtb_SFunction[2]; |
| Inputs: Global, reusable,
overwritable
| ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_GLOBAL); ssSetInputPortOverWritable(S, 0, TRUE); ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_GLOBAL); | The model.h file
defines a block signals structure with a single element to store the
S-function's input and output./* Block signals (auto storage) */
typedef struct {
real_T SFunction[2];
} BlockIO_sl_directlook;The model.c file
uses this element of the structure in calculations of the S-function's
input and output signals. /* Sin: '<Root>/Sine Wave' */
sl_directlook_B.SFunction[0] = sin ...
/* snip */
/*S-Function Block:<Root>/S-Function*/
{
const real_T *xData =
&sl_directlook_P.SFunction_XData[0] |
| Inputs: Local, not reusable
| ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_LOCAL); ssSetInputPortOverWritable(S, 0, FALSE); ssSetOutputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_LOCAL); | The model.c file
declares local variables for the S-function's input and output in
the output function/* local block i/o variables */ real_T rtb_SineWave[2]; real_T rtb_SFunction[2]; |
| Inputs: Global, not reusable
| ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL); ssSetInputPortOverWritable(S, 0, FALSE); ssSetOutputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL); | The model.h file
defines a block signal structure with individual elements to store
the S-function's input and output./* Block signals (auto storage) */
typedef struct {
real_T SineWave[2];
real_T SFunction[2];
} BlockIO_sl_directlook;The model.c file
uses the different elements in this structure when calculating the
S-function's input and output. /* Sin: '<Root>/Sine Wave' */
sl_directlook_B.SineWave[0] = sin ...
/* snip */
/*S-Function Block:<Root>/S-Function*/
{
const real_T *xData =
&sl_directlook_P.SFunction_XData[0] |
![]() | Writing S-Functions That Support Expression Folding | Writing S-Functions That Specify Sample Time Inheritance Rules | ![]() |

Learn more about Simulink through this collection of videos, articles, technical literature and the Getting Started with Simulink Guide.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |