Convert Level-1 C MEX S-Functions
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
matlabroot/toolbox/simulink/blocks/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
. ThessGetX
macro has been removed.Access the discrete states using
ssGetRealDiscStates(S)
. ThessGetX
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 fromstatic 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
, andu
are not explicitly passed in to Level-2 S-functions, you must usessGetInputPortSignal
to access inputsssGetOutputPortSignal
to access the outputsssGetContStates
orssGetRealDiscStates
to access the states
The
mdlUpdate
function prototype has changed fromvoid 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 themex
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 addmatlabroot/simulink/include matlabroot/extern/include
to the path (be sure to build with alignment set to 8).
Obsolete Macros
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) | , ssGetInputPortSignal (S,port ) |
ssGetY(S) |
|
ssGetX(S) |
|
ssGetStatus(S) | Normally not used, but is
available. |
ssSetStatus(S,msg) |
|
ssGetSizes(S) | Specific call for the wanted item (i.e., )
|
ssGetMinStepSize(S) | No longer supported |
ssGetPresentTimeEvent(S,sti) |
|
ssGetSampleTimeEvent(S,sti) |
|
ssSetSampleTimeEvent(S,t) |
|
ssGetOffsetTimeEvent(S,sti) |
|
ssSetOffsetTimeEvent(S,sti,t) |
|
ssIsSampleHitEvent(S,sti,tid)
|
|
ssGetNumInputArgs(S)
|
|
ssSetNumInputArgs(S, numInputArgs) |
|
ssGetNumArgs(S) |
|
ssGetArg(S,argNum) |
|
ssGetNumInputs |
and
|
ssSetNumInputs |
and
|
ssGetNumOutputs |
and
|
ssSetNumOutputs |
and
|
See Also
Level-2 MATLAB S-Function | S-Function Builder | S-Function | MATLAB Function
Related Topics
1 UNIX is a registered trademark of The Open Group in the United States and other countries.