Start and Terminate Actions Within Legacy Functions
This example shows you how to use the Legacy Code Tool to integrate legacy C functions that have start and terminate actions.
The Legacy Code Tool allows you to:
Provide the legacy function specification,
Generate a C-MEX S-function that is used during simulation to call the legacy code, and
Compile and build the generated S-function for simulation.
Providing the Legacy Function Specification
Functions provided with the Legacy Code Tool take a specific data structure or array of structures as the argument. The data structure is initialized by calling the function legacy_code()
using initialize
as the first input. After initializing the structure, you have to assign its properties to values corresponding to the legacy code being integrated. The prototypes of the legacy functions being called in this example are:
void initFaultCounter(unsigned int *counter)
void openLogFile(void **fid)
void incAndLogFaultCounter(void *fid, unsigned int *counter, double time)
void closeLogFile(void **fid)
To open the model and files, click Open Model. The legacy source code is found in the files your_types.h
, fault.h
, and fault.c
.
% sldemo_sfun_fault def = legacy_code('initialize'); def.SFunctionName = 'sldemo_sfun_fault'; def.InitializeConditionsFcnSpec = 'initFaultCounter(uint32 work2[1])'; def.StartFcnSpec = 'openLogFile(void **work1)'; def.OutputFcnSpec = 'incAndLogFaultCounter(void *work1, uint32 work2[1], double u1)'; def.TerminateFcnSpec = 'closeLogFile(void **work1)'; def.HeaderFiles = {'fault.h'}; def.SourceFiles = {'fault.c'}; def.IncPaths = {'sldemo_lct_src'}; def.SrcPaths = {'sldemo_lct_src'}; def.Options.useTlcWithAccel = false;
Generating and Compiling an S-Function for Use During Simulation
The function legacy_code()
is called again with the first input set to generate_for_sim
in order to automatically generate and compile the C-MEX S-function according to the description provided by the input argument def
. This S-function is used to call the legacy functions in simulation. The source code for the S-function is found in the file sldemo_sfun_fault.c.
legacy_code('generate_for_sim', def);
### Start Compiling sldemo_sfun_fault mex('-I/tmp/Bdoc24b_2725827_2542211/tp61fd10c4/simulink_features-ex33158503/sldemo_lct_src', '-I/tmp/Bdoc24b_2725827_2542211/tp61fd10c4/simulink_features-ex33158503', '-c', '-outdir', '/tmp/Bdoc24b_2725827_2542211/tpcc57904f_56aa_431a_a9b4_54f87755ddcd', '/tmp/Bdoc24b_2725827_2542211/tp61fd10c4/simulink_features-ex33158503/sldemo_lct_src/fault.c') Building with 'gcc'. MEX completed successfully. mex('sldemo_sfun_fault.c', '-I/tmp/Bdoc24b_2725827_2542211/tp61fd10c4/simulink_features-ex33158503/sldemo_lct_src', '-I/tmp/Bdoc24b_2725827_2542211/tp61fd10c4/simulink_features-ex33158503', '/tmp/Bdoc24b_2725827_2542211/tpcc57904f_56aa_431a_a9b4_54f87755ddcd/fault.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling sldemo_sfun_fault ### Exit
Generating an rtwmakecfg.m File for Code Generation
After the TLC block file is created, the function legacy_code()
can be called again with the first input set to rtwmakecfg_generate
in order to generate an rtwmakecfg.m
file to support code generation through Simulink® Coder™. Generate the rtwmakecfg.m
file if the required source and header files for the S-functions are not in the same directory as the S-functions, and you want to add these dependencies in the makefile
produced during code generation.
Note: Complete this step only if you are going to simulate the model in accelerated mode.
legacy_code('rtwmakecfg_generate', def);
Generating a Masked S-Function Block for Calling the Generated S-Function
After the C-MEX S-function source is compiled, the function legacy_code()
can be called again with the first input set to slblock_generate
in order to generate a masked S-function block that is configured to call that S-function. The block is placed in a new model and can be copied to an existing model.
% legacy_code('slblock_generate', def);
Integrate the Legacy Code
The model sldemo_lct_start_term
shows integration with the legacy code. The subsystem TestFixpt
serves as a harness for the call to the legacy C function, and the scope compares the output of the function with the output of the built-in Simulink® product block; the results should be identical.
open_system('sldemo_lct_start_term') open_system('sldemo_lct_start_term/TestFault') sim('sldemo_lct_start_term');