Inline S-Functions with TLC
timesN
Tutorial Overview
Objective: To understand how TLC works with an S-function.
Open the Example:
openExample('simulinkcoder/AdviceAboutTLCTutorialsExample') cd('tlctutorial/timesN')
In this tutorial, you generate versions of C code for existing S-function
timesN
.
The tutorial includes these steps:
Noninlined Code Generation — Via SimStructs and generic API
Why Use TLC to Inline S-Functions? — Benefits of inlining
Create an Inlined S-Function — Via custom TLC code
A later tutorial provides information and practice with “wrapping” S-functions.
Noninlined Code Generation
The tutorial folder tlctutorial/timesN
in your working folder
contains Simulink® S-function timesN.c
.
In this exercise, you generate noninlined code from the model
sfun_xN
.
Find the file
rename_timesN.tlc
intlctutorial/timesN
. Rename this file totimesN.tlc
. This allows you to generate code.In the MATLAB® Command Window, create a MEX-file for the S-function:
mex timesN.c
This avoids picking up the version shipped with Simulink.
Open the model
sfun_xN
, which uses thetimesN
S-function. The block diagram looks like this.Open the Configuration Parameters dialog box and select the Solver pane.
Set Stop time to
10.0
.Set the Solver Options.
Type to
Fixed-step
Solver to
Discrete (no continuous states)
Fixed-step size (fundamental sample time) to
0.01
Select the Optimization pane, and make sure that Default parameter behavior is set to
Tunable
.Select the Code Generation > Comments pane, and notice that Include comments is checked by default.
Select the Code Generation pane and check Generate code only.
Click Apply.
Press Ctrl+B to generate C code for the model.
Open the resulting file
sfun_xN_grt_rtw/sfun_xN.c
and view thesfun_xN_output
portion, shown below.
/* Model output function */ static void sfun_xN_output(int_T tid) { /* Sin: '<Root>/Sin' */ sfun_xN_B.Sin = sin(sfun_xN_M->Timing.t[0] * sfun_xN_P.Sin_Freq + sfun_xN_P.Sin_Phase) * sfun_xN_P.Sin_Amp + sfun_xN_P.Sin_Bias; /* S-Function Block: <Root>/S-Function */ /* Multiply input by 3.0 */ sfun_xN_B.timesN_output = sfun_xN_B.Sin * 3.0; /* Outport: '<Root>/Out' */ sfun_xN_Y.Out = sfun_xN_B.timesN_output; UNUSED_PARAMETER(tid); }
Comments appear in the code because, in the Code Generation > Comments pane of the Configuration Parameters dialog box, Include comments is selected by default.
Why Use TLC to Inline S-Functions?
The code generator includes a generic API that you can use to invoke user-written algorithms and drivers. The API includes a variety of callback functions — for initialization, output, derivatives, termination, and so on — as well as data structures. Once coded, these are instantiated in memory and invoked during execution via indirect function calls. Each invocation involves stack frames and other overhead that adds to execution time.
In a real-time environment, especially when many solution steps are involved, generic API calls can be unacceptably slow. The code generator can speed up S-functions in standalone applications that it generates by embedding user-written algorithms within auto-generated functions, rather than indirectly calling S-functions via the generic API. This form of optimization is called inlining. TLC inlines S-functions, resulting in faster, optimized code.
You should understand that TLC is not a substitute for writing C code S-functions. To invoke custom blocks within Simulink, you still have to write S-functions in C (or as MATLAB files), since simulations do not make use of TLC files. You can, however, prepare TLC files that inline specified S-functions to make your target code much more efficient.
Create an Inlined S-Function
TLC creates an inlined S-function whenever it detects a
.tlc
file with the same name as an S-function. Assuming the
.tlc
file has the expected form, it directs construction of code that
functionally duplicates the external S-function without incurring API overhead. See how this
process works by completing the following steps:
If you have not done so already, find the file
rename_timesN.tlc
intlctutorial/timesN
. Rename this file totimesN.tlc
, so you can use it to generate code. The executable portion of the file is%implements "timesN" "C" %% Function: Outputs =========================================================== %% %function Outputs(block, system) Output %assign gain =SFcnParamSettings.myGain /* %<Type> Block: %<Name> */ %% /* Multiply input by %<gain> */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * %<gain>; %endroll %endfunction
Create the inline version of the S-function.
On the Optimization pane of the Configuration Parameters dialog box, set Default parameter behavior to
Inlined
, and click Apply.Change the diagram’s label from
model: sfun_xN
tomodel: sfun_xN_ilp
.Save the model as
sfun_x2_ilp
.Press Ctrl+B. Source files are created in a new subfolder called
sfun_xN_ilp_grt_rtw
.Inspect the code in generated file
sfun_xN_ilp.c
:/* Model output function */ static void sfun_xN_ilp_output(int_T tid) { /* Sin: '<Root>/Sin' */ sfun_xN_ilp_B.Sin = sin(sfun_xN_ilp_M->Timing.t[0]); /* S-Function Block: <Root>/S-Function */ /* Multiply input by 3.0 */ sfun_xN_ilp_B.timesN_output = sfun_xN_ilp_B.Sin * 3.0; /* Outport: '<Root>/Out' */ sfun_xN_ilp_Y.Out = sfun_xN_ilp_B.timesN_output; UNUSED_PARAMETER(tid); }
Note
When the code generator produces code and builds executables, it creates or uses a specific subfolder (called the build folder) to hold source, object, and make files. By default, the build folder is named
.model
_grt_rtwNotice that setting Default parameter behavior to
Inlined
did not change the code. This is because TLC inlines S-functions.
Continue the exercise by creating a standalone simulation.
In the Code Generation pane of the Configuration Parameters dialog box, clear Generate code only and click Apply.
In the Data Import/Export pane of the Configuration Parameters dialog box, check Output.
This specification causes the model’s output data to be logged in your MATLAB workspace.
Press Ctrl+B to generate code, compile, and link the model into an executable, named
sfun_xN_ilp.exe
(or, on UNIX® systems,sfun_xN_ilp
).Confirm that the
timesN.tlc
file produces expected output by running the standalone executable. To run it, in the MATLAB Command Window, type!sfun_xN_ilp
The following response appears:
** starting the model ** ** created sfun_xN_ilp.mat **
View or plot the contents of the
sfun_xN_ilp.mat
file to verify that the standalone model generated sine output ranging from -3 to +3. In the MATLAB Command Window, typeload sfun_xN_ilp.mat plot (rt_yout)
Tip
For UNIX platforms, run the executable program in the Command Window with the syntax
!./
executable_name
. If
preferred, run the executable program from an OS shell with the syntax
./
executable_name
. For more
information, see Run External Commands, Scripts, and Programs.