| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Simulink |
| Contents | Index |
| Learn more about Simulink |
| On this page… |
|---|
Guidelines for Converting Level-1 C MEX S-Functions to Level-2 |
Level-2 S-functions were introduced with Simulink version 2.2. Level-1 S-functions refer to S-functions that were written to work with Simulink version 2.1 and previous releases. Level-1 S-functions are compatible with Simulink version 2.2 and subsequent releases; you can use them in new models without making any code changes. However, to take advantage of new features in S-functions, Level-1 S-functions must be updated to Level-2 S-functions. Here are some guidelines:
Start by looking at simulink/src/sfunctmpl_doc.c. This template S-function file concisely summarizes Level-2 S-functions.
At the top of your S-function file, add this define:
#define S_FUNCTION_LEVEL 2
Update the contents of mdlInitializeSizes. In particular, add the following error handling for the number of S-function parameters:
ssSetNumSFcnParams(S, NPARAMS); /*Number of expected parameters*/
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}
Set up the inputs using:
if (!ssSetNumInputPorts(S, 1)) return; /*Number of input ports */
ssSetInputPortWidth(S, 0, width); /* Width of input
port one (index 0)*/
ssSetInputPortDirectFeedThrough(S, 0, 1); /* Direct feedthrough
or port one */
ssSetInputPortRequiredContiguous(S, 0);
Set up the outputs using:
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, width); /* Width of output port
one (index 0) */
If your S-function has a nonempty mdlInitializeConditions, update it to the following form:
#define MDL_INITIALIZE_CONDITIONS
static void mdlInitializeConditions(SimStruct *S)
{
}
Otherwise, delete the function.
Access the continuous states using ssGetContStates. The ssGetX macro has been removed.
Access the discrete states using ssGetRealDiscStates(S). The ssGetX macro has been removed.
For mixed continuous and discrete state S-functions, the state vector no longer consists of the continuous states followed by the discrete states. The states are saved in separate vectors and hence might not be contiguous in memory.
The mdlOutputs prototype has changed from
static void mdlOutputs( real_T *y, const real_T *x, const real_T *u, SimStruct *S, int_T tid)
to
static void mdlOutputs(SimStruct *S, int_T tid)
Since y, x, and u are not explicitly passed in to Level-2 S-functions, you must use
ssGetInputPortSignal to access inputs
ssGetOutputPortSignal to access the outputs
ssGetContStates or ssGetRealDiscStates to access the states
The mdlUpdate function prototype has changed from
void mdlUpdate(real_T *x, real_T *u, Simstruct *S, int_T tid)
to
void mdlUpdate(SimStruct *S, int_T tid)
If your S-function has a nonempty mdlUpdate, update it to this form:
#define MDL_UPDATE
static void mdlUpdate(SimStruct *S, int_T tid)
{
}
Otherwise, delete the function.
If your S-function has a nonempty mdlDerivatives, update it to this form:
#define MDL_DERIVATIVES
static void mdlDerivatives(SimStruct *S)
{
}
Otherwise, delete the function.
Replace all obsolete SimStruct macros. See Obsolete Macros for a complete list of obsolete macros.
When converting Level-1 S-functions to Level-2 S-functions, you should build your S-functions with full (i.e., highest) warning levels. For example, if you have gcc on a UNIX[1] system, use these options with the mex utility.
mex CC=gcc CFLAGS=-Wall sfcn.c
If your system has Lint, use this code.
lint -DMATLAB_MEX_FILE -I<matlabroot>/simulink/include
-Imatlabroot/extern/include sfcn.c
On a PC, to use the highest warning levels, you must create a project file inside the integrated development environment (IDE) for the compiler you are using. Within the project file, define MATLAB_MEX_FILE and add
matlabroot/simulink/include matlabroot/extern/include
to the path (be sure to build with alignment set to 8).
The following macros are obsolete. Replace each obsolete macro with the macro specified in the following table.
Obsolete Macro | Replace with |
|---|---|
ssGetU(S), ssGetUPtrs(S) | ssGetInputPortSignalPtrs(S,port), ssGetInputPortSignal(S,port) |
ssGetY(S) | ssGetOutputPortRealSignal(S,port) |
ssGetX(S) | |
ssGetStatus(S) | Normally not used, but ssGetErrorStatus(S) is available. |
ssSetStatus(S,msg) | ssSetErrorStatus(S,msg) |
ssGetSizes(S) | Specific call for the wanted item (i.e., ssGetNumContStates(S)) |
ssGetMinStepSize(S) | No longer supported. |
ssGetPresentTimeEvent(S,sti) | ssGetTaskTime(S,sti) |
ssGetSampleTimeEvent(S,sti) | ssGetSampleTime(S,sti) |
ssSetSampleTimeEvent(S,t) | ssSetSampleTime(S,sti,t) |
ssGetOffsetTimeEvent(S,sti) | ssGetOffsetTime(S,sti) |
ssSetOffsetTimeEvent(S,sti,t) | ssSetOffsetTime(S,sti,t) |
ssIsSampleHitEvent(S,sti,tid) | ssIsSampleHit(S,sti,tid) |
ssGetNumInputArgs(S) | |
ssSetNumInputArgs(S, numInputArgs) | ssSetNumSFcnParams(S,numInputArgs) |
ssGetNumArgs(S) | |
ssGetArg(S,argNum) | ssGetSFcnParam(S,argNum) |
ssGetNumInputs | ssGetNumInputPorts(S) and ssGetInputPortWidth(S,port) |
ssSetNumInputs | ssSetNumInputPorts(S,nInputPorts) and ssSetInputPortWidth(S,port,val) |
ssGetNumOutputs | ssGetNumOutputPorts(S) and ssGetOutputPortWidth(S,port) |
ssSetNumOutputs | ssSetNumOutputPorts(S,nOutputPorts) and ssSetOutputPortWidth(S,port,val) |
[1] UNIX is a registered trademark of The Open Group in the United States and other countries.
![]() | Debugging C MEX S-Functions | Creating C++ S-Functions | ![]() |

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 |