Target Language Compiler | ![]() ![]() |
Inlining M-File S-Functions
All of the functionality of M-file S-functions can be inlined in the generated code. Writing a block target file for an M-file S-function is essentially identical to the process for a C MEX S-function.
Note that while you can fully inline an M-file S-function to achieve top performance--even with Simulink Accelerator--the MATLAB Math Library is not included with Real-Time Workshop, so any high-level MATLAB commands and functions you use in the M-file S-function must be written by hand in the block target file.
A quick example will illustrate the equivalence of C MEX and M-file S-functions for code generation. The M-file S-function timestwo.m
is equivalent to the C MEX S-function timestwo
. In fact, the TLC file for the C MEX S-function timestwo
will work for the M-file S-function timestwo.m
as well! Since TLC only requires the `root' name of the S-function and not its type, it is independent of the type of S-function. In the case of timestwo
, one line determines what the TLC file will be used for
To try this out for yourself, copy file timestwo.m
from matlabroot
/toolbox/simulink/blocks/
to a temporary directory, then copy the file timestwo.tlc
from matlabroot
/toolbox/simulink/blocks/tlc_c/
to the same temporary directory. In MATLAB, cd
to the temporary directory and make a Simulink model with an S-function block that calls timestwo
. Since the MATLAB search path will find timestwo.m
in the current directory before finding the C MEX S-function timestwo
in the matlabpath
, Simulink will use the M-file S-function for simulation. Verify which S-function will be used by typing the MATLAB command
The answer you see will be the M-file S-function timestwo.m
in the temporary directory. Here is the sample model.
Upon generating code, you will find that the timestwo.tlc
file was used to inline the M-file S-function with code that looks like this (with an input signal width of 5 in this example):
/* S-Function Block: <Root>/m-file S-Function */ /* Multiply input by two */ { int_T i1; const real_T *u0 = &rtB.Gain[0]; real_T *y0 = &rtB.m_file_S_Function[0]; for (i1=0; i1 < 5; i1++) { y0[i1] = u0[i1] * 2.0; } }
As expected, each of the inputs, u0[i1]
, is multiplied by 2.0 to form the output value. The Outputs
method in the block target file used to generate this code was
%function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% /* Multiply input by two */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * 2.0; %endroll %endfunction
Alter these temporary copies of the M-file S-function and the TLC file to see how they interact -- start out by just changing the comments in the TLC file and see it show up in the generated code, then work up to algorithmic changes.
![]() | A Complete Example | Inlining Fortran (F-MEX) S-Functions | ![]() |