How to configure Legacy Code Tool to generate an S-Function compatible with Speedgoat & Simulink Real-Time R2020b and later?

How do I configure the Legacy Code Tool (LCT) to generate an S-function compatible with Speedgoat & Simulink Real-Time (SLRT) R2020b and later?

 Accepted Answer

Starting in R2020b, SLRT uses a C++ code generation target (slrealtime.tlc/speedgoat.tlc) instead of a C code generation target (slrt.tlc). Follow the steps below to ensure the S-function generated by Legacy Code Tool is compatible with SLRT in newer releases:
1) Set the target language to 'C++':
Set the "language" S-function option in the Legacy Code Tool to 'C++'.  Otherwise, you will receive the following error when you try to build the model for SLRT:
Simulink Coder Fatal: This S-Function generated by the Legacy Code Tool must be only used with the C Target Language
See the following doc page on S-Functions options with the Legacy Code Tool 'specs' argument: Legacy Code Tool Specification.
2) Make your legacy C code compatible with C++:
Any legacy C code must be compatible with C++. Otherwise, the MEX compilation of the S-function will already fail for the simulation target with an "undefined reference" or "LNK2019: unresolved external symbol" linker error, depending on the MEX compiler used. An easy solution is to add C++ linkage guards (extern "C") around existing C declarations as described in the SLRT documentation:
There are three ways to apply this solution when using the Legacy Code Tool:
  1. Adding the C++ linkage guards to the C-style headers themselves (= modifying the original header files).
  2. Adding a thin wrapper header file around C-style headers (= not modifying the original header files, but adding an additional header file).
If the original header files can't be modified, we recommend following the 2nd approach (see Example below).
3) Cross-compile any external libraries:
Note that any additional included runtime libraries (.dll, .lib) must be compiled for the SLRT RTOS. See:

Example:

The attached "SLRT_LCT_examples.zip" shows both solutions outlined above. The external code defines a C function "multiply_by_two" in '/extern/src/doubleIt.c', which is declared in the 'extern/includes/doubleIt.h' header. For the recommended solution 2, a wrapper header file is added in '/wrapper/doubleIt_wrapper.h':
#ifdef __cplusplus
extern "C" {
#endif
#include "doubleIt.h"
#ifdef __cplusplus
}
#endif
 The resulting MATLAB code for running the Legacy Code Tool is the following:
%% LCT Code for SLRT R2020b and later - C++-MEX S-Function
def = legacy_code('initialize');
def.SFunctionName = 'multiply_by_two_sfun';
def.OutputFcnSpec = 'int32 y1 = multiply_by_two(int32 u1)';
% Reference wrapper header:
def.HeaderFiles = {'doubleIt_wrapper.h'};
def.SourceFiles = {'doubleIt.c'};
def.IncPaths = {'extern/includes','wrapper'};
def.SrcPaths = {'extern/src'};
% Use C++ language option:
def.Options.language='C++';
% Run legacy_code:
legacy_code('generate_for_sim', def);
legacy_code('rtwmakecfg_generate', def);
model = 'testmodel';
legacy_code('slblock_generate', def, model);
if isMATLABReleaseOlderThan('R2024a')
set_param(model,'SystemTargetFile','slrealtime.tlc')
else
set_param(model,'SystemTargetFile','speedgoat.tlc')
end
set_param(model,'SolverType','Fixed-step');
Further reading:
Refer to the documentation for your release:

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!