Contents

Basic C MEX S-Function

Introducing an Example of a Basic C MEX S-Function

This section presents an example of a C MEX S-function that you can use as a model for creating simple C S-functions. The example S-function timestwo.ctimestwo.c outputs twice its input.

The following model uses the timestwo S-function to double the amplitude of a sine wave and plot it in a scope.

The block dialog for the S-function specifies timestwo as the S-function name; the parameters field is empty.

The timestwo S-function contains the S-function callback methods shown in this figure. At the end of S-function, include the code snippet as described in Simulink/Simulink Coder Interfaces.

The contents of timestwo.c are shown below. A description of the code is provided after the example.

#define S_FUNCTION_NAME timestwo /* Defines and Includes */
#define S_FUNCTION_LEVEL 2

#include "simstruc.h"
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return; /* Parameter mismatch reported by the Simulink engine*/
    }

    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);
    ssSetInputPortDirectFeedThrough(S, 0, 1);

    if (!ssSetNumOutputPorts(S,1)) return;
    ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);

    ssSetNumSampleTimes(S, 1);

    /* Take care when specifying exception free code - see sfuntmpl.doc */
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
    }
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
    int_T i;
    InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
    real_T *y = ssGetOutputPortRealSignal(S,0);
    int_T width = ssGetOutputPortWidth(S,0);

    for (i=0; i<width; i++) {
        *y++ = 2.0 *(*uPtrs[i]);
    }
}
static void mdlTerminate(SimStruct *S){}

#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif

This example has three parts:

  • Defines and includes

  • Callback method implementations

  • Simulink® (or Simulink Coder™) product interfaces

Defines and Includes

The example starts with the following define statements.

#define S_FUNCTION_NAME  timestwo
#define S_FUNCTION_LEVEL 2

The first define statement specifies the name of the S-function (timestwo). The second define statement specifies that the S-function is in the Level 2 format (for more information about Level 1 and Level 2 S-functions, see Convert Level-1 C MEX S-Functions).

After defining these two items, the example includes simstruc.hsimstruc.h, which is a header file that gives access to the SimStruct data structure and the MATLAB® Application Program Interface (API) functions.

#define S_FUNCTION_NAME  timestwo
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

The simstruc.h file defines a data structure, called the SimStruct, that the Simulink engine uses to maintain information about the S-function. The simstruc.h file also defines macros that enable your MEX file to set values in and get values (such as the input and output signal to the block) from the SimStruct (see About SimStruct Functions).

Callback Method Implementations

The next part of the timestwo S-function contains implementations of required callback methods.

mdlInitializeSizes

The Simulink engine calls mdlInitializeSizes to inquire about the number of input and output ports, sizes of the ports, and any other information (such as the number of states) needed by the S-function.

The timestwo implementation of mdlInitializeSizes specifies the following size information:

  • Zero parameters

    Therefore, the S-function parameters field of the S-Function Block Parameters dialog box must be empty. If it contains any parameters, the engine reports a parameter mismatch.

  • One input port and one output port

    The widths of the input and output ports are dynamically sized. This tells the engine that the S-function can accept an input signal of any width. By default, the widths of dynamically sized input and output port are equal when the S-function has only one input and output port.

  • One sample time

    The mdlInitializeSampleTimes callback method specifies the actual value of the sample time.

  • Exception free code

    Specifying exception-free code speeds up execution of your S-function. You must take care when specifying this option. In general, if your S-function is not interacting with the MATLAB environment, you can safely specify this option. For more details, see Simulink Engine Interaction with C S-Functions.

mdlInitializeSampleTimes

The Simulink engine calls mdlInitializeSampleTimes to set the sample times of the S-function. A timestwo block executes whenever the driving block executes. Therefore, it has a single inherited sample time, INHERITED_SAMPLE_TIME.

mdlOutputs

The engine calls mdlOutputs at each time step to calculate the block outputs. The timestwo implementation of mdlOutputs multiplies the input signal by 2 and writes the answer to the output.

The line:

InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);

accesses the input signal. The ssGetInputPortRealSignalPtrs macro returns a vector of pointers, which you must access using

*uPtrs[i]

For more details on accessing input signals, see Accessing Signals Using Pointers.

The line:

real_T *y = ssGetOutputPortRealSignal(S,0);

accesses the output signal. The ssGetOutputPortRealSignal macro returns a pointer to an array containing the block outputs.

The line:

int_T width = ssGetOutputPortWidth(S,0);

obtains the width of the signal passing through the block. The S-function loops over the inputs to compute the outputs.

mdlTerminate

The engine calls mdlTerminate to provide the S-function with an opportunity to perform tasks at the end of the simulation. This is a mandatory S-function routine. The timestwo S-function does not perform any termination actions, and this routine is empty.

Simulink/Simulink Coder Interfaces

At the end of the S-function, include the following code to attach your S-function to either the Simulink or Simulink Coder products.

#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif

This trailer is required at the end of every S-function. If it is omitted, any attempt to compile your S-function will abort with a failure during build of exports file error message.

Building the Timestwo Example

To compile this S-function, enter

mex timestwo.c

at the command line. The mex command compiles and links the timestwo.c file to create a dynamically loadable executable for the Simulink software to use.

The resulting executable is referred to as a MEX S-function, where MEX stands for "MATLAB Executable." The MEX file extension varies from platform to platform. For example, on a 32–bit Microsoft® Windows® system, the MEX file extension is .mexw32.

Was this topic helpful?