Products & Services Solutions Academia Support User Community Company

Learn more about Real-Time Workshop   

Writing S-Functions That Specify Port Scope and Reusability

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:

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:

The reusability setting indicates if the memory associated with an input or output port can be overwritten. To reuse input and output port memory:

  1. Indicate the ports are reusable using either the SS_REUSABLE_AND_LOCAL or SS_REUSABLE_AND_GLOBAL option in the ssSetInputPortOptimOpts and ssSetOutputPortOptimOpts macros

  2. Indicate the input port memory is overwritable using ssSetInputPortOverWritable

  3. 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 reusabilityS-function mdlInitializeSizes codeGenerated 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


Outputs:
Global, reusable

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


Outputs:
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


Outputs:
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]

  


Related Products & Applications

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