Writing S-Functions | ![]() ![]() |
MEX S-Function Wrapper
Creating S-functions using an S-function wrapper allows you to insert your C code algorithms in Simulink and the Real-Time Workshop with little or no change to your original C code function. A MEX S-function wrapper is an S-function that calls code that resides in another module. In effect, the wrapper binds your code to Simulink. A TLC S-function wrapper is a TLC file that specifies how the Real-Time Workshop should call your code (the same code that was called from the C-MEX S-function wrapper).
Suppose you have an algorithm (i.e., a C function) called my_alg
that resides in the file my_alg.c
. You can integrate my_alg
into Simulink by creating a MEX S-function wrapper (e.g., wrapsfcn.c
). Once this is done, Simulink can call my_alg
from an S-Function block. However, the Simulink S-function contains a set of empty functions that Simulink requires for various API-related purposes. For example, although only mdlOutputs
calls my_alg
, Simulink calls mdlTerminate
as well, even though this S-function routine performs no action.
You can integrate my_alg
into the Real-Time Workshop generated code (i.e., embed the call to my_alg
in the generated code) by creating a TLC S-function wrapper (e.g., wrapsfcn.tlc
). The advantage of creating a TLC S-function wrapper is that the empty function calls can be eliminated and the overhead of executing the mdlOutputs
function and then the my_alg
function can be eliminated.
Wrapper S-functions are useful when you are creating new algorithms that are procedural in nature or when you are integrating legacy code into Simulink. However, if you want to create code that is:
then you must create a fully inlined TLC file for your S-function.
This figure illustrates the wrapper S-function concept.
Figure 8-1: How S-Functions Interface with Hand-Written Code
Using an S-function wrapper to import algorithms in your Simulink model means that the S-function serves as an interface that calls your C code algorithms from mdlOutputs
. S-function wrappers have the advantage that you can quickly integrate large stand-alone C code into your model without having to make changes to the code.
This is an example of a model that includes an S-function wrapper.
Figure 8-1: An Example Model That Includes an S-Function Wrapper
There are two files associated with the wrapsfcn
block, the S-function wrapper and the C code that contains the algorithm. This is the S-function wrapper code for this example, called wrapsfcn.c
.
#define S_FUNCTION_NAME wrapsfcn #define S_FUNCTION_LEVEL 2 #include "simstruc.h"extern real_T my_alg(real_T u); /* * mdlInitializeSizes - initialize the sizes array */ static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams( S, 0); /*number of input arguments*/ if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, 1); ssSetNumSampleTimes( S, 1); } /* * mdlInitializeSampleTimes - indicate that this S-function runs * at the rate of the source (driving block) */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); } /* * mdlOutputs - compute the outputs by calling my_alg, which * resides in another module, my_alg.c */ static void mdlOutputs(SimStruct *S, int_T tid) { InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0);
*y = my_alg(*uPtrs[0]); } /* * mdlTerminate - called when the simulation is terminated. */ 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
The S-function routine mdlOutputs
contains a function call to my_alg
, which is the C function that contains the algorithm that the S-function performs. This is the code for my_alg.c
:
The wrapper S-function wrapsfcn
calls my_alg
, which computes u * 2.0
. To build wrapsfcn.mex
, use the following command:
![]() | Writing Wrapper S-Functions | TLC S-Function Wrapper | ![]() |