Main Content

Import Calls to External Code into Generated Code with Legacy Code Tool

Legacy Code Tool and Code Generation

You can use the Simulink®Legacy Code Toolto generate fully inlined C MEX S-functions for legacy or custom code. The S-functions are optimized for embedded components, such as device drivers and lookup tables, and they call existing C or C++ functions.

Note

The Legacy Code Tool can interface with C++ functions, but not C++ objects. To work around this issue so that the tool can interface with C++ objects, seeLegacy Code Tool Limitations.

You can use the tool to:

  • Compile and build the generated S-function for simulation.

  • Generate a masked S-Function blockthat is configured to call the existing external code.

If you want to include these types of S-functions in models for which you intend to generate code, use the tool to generate a TLC block file. The TLC block file specifies how the generated code for a model calls the existing C or C++ function.

If the S-function depends on files in folders other than the folder containing the S-function dynamically loadable executable file, use the tool to generate ansFunction_makecfg.morrtwmakecfg.mfile for the S-function. Generating the file maintains those dependencies when you build a model that includes the S-function. For example, for some applications, such as custom targets, you might want to locate files in a target-specific location. The build process looks forsFunction_makecfg.morrtwmakecfg.min the same folder as the S-function dynamically loadable executable and calls the function in the file.

For more information, seeIntegrate C Functions Using Legacy Code Tool.

Generate Inlined S-Function Files for Code Generation

Depending on the code generation requirements of your application, to generate code for a model that uses the S-function, do either of the following:

  • Generate one.cpp文件为内联函数。遗留的鳕鱼e Tool data structure, set the value of theOptions.singleCPPMexFilefield totruebefore generating the S-function source file from your existing C function. For example:

    def.Options.singleCPPMexFile = true; legacy_code('sfcn_cmex_generate', def);

  • Generate a source file and a TLC block file for the inlined S-function. For example:

    def.Options.singleCPPMexFile = false; legacy_code('sfcn_cmex_generate', def); legacy_code('sfcn_tlc_generate', def);

singleCPPMexFile Limitations

You cannot set thesingleCPPMexFilefield totrueif

  • Options.language='C++'

  • You use one of the following Simulink objects with theIsAliasproperty set totrue:

    • Simulink.Bus

    • Simulink.AliasType

    • Simulink.NumericType

  • The Legacy Code Tool function specification includes avoid*orvoid**to represent scalar work data for a state argument

  • HeaderFilesfield of the Legacy Code Tool structure specifies multiple header files

Apply Code Style Settings to Legacy Functions

To apply the model configuration parameters for code style to a legacy function:

  1. Initialize the Legacy Code Tool data structure. For example:

    def = legacy_code('initialize');
  2. In the data structure, set the value of theOptions.singleCPPMexFilefield totrue. For example:

    def.Options.singleCPPMexFile = true;

To check the setting, enter:

def.Options.singleCPPMexFile

singleCPPMexFile Limitations

You cannot set thesingleCPPMexFilefield totrueif

  • Options.language='C++'

  • You use one of the following Simulink objects with theIsAliasproperty set totrue:

    • Simulink.Bus

    • Simulink.AliasType

    • Simulink.NumericType

  • The Legacy Code Tool function specification includes avoid*orvoid**to represent scalar work data for a state argument

  • HeaderFilesfield of the Legacy Code Tool structure specifies multiple header files

Address Dependencies on Files in Different Locations

By default, the Legacy Code Tool assumes that files on which an S-function depends reside in the same folder as the dynamically loadable executable file for the S-function. If your S-function depends on files that reside elsewhere and you are using the template makefile build process, generate ansFunction_makecfg.morrtwmakecfg.mfilefor the S-function. For example, you might generate this file if your Legacy Code Tool data structure defines compilation resources as path names.

To generate thesFunction_makecfg.morrtwmakecfg.mfile, call thelegacy_codefunction with'sfcn_makecfg_generate'or'rtwmakecfg_generate'as the first argument, and the name of the Legacy Code Tool data structure as the second argument. For example:

legacy_code('sfcn_makecfg_generate', lct_spec);

If you use multiple registration files in the same folder and generate an S-function for each file with a single call tolegacy_code, the call tolegacy_codethat specifies'sfcn_makecfg_generate'or'rtwmakecfg_generate'must be common to all registration files. For more information, seeHandling Multiple Registration Files.

为考试ple, if you definedefsas an array of Legacy Code Tool structures, you calllegacy_codewith'sfcn_makecfg_generate'once.

defs = [defs1(:);defs2(:);defs3(:)]; legacy_code('sfcn_makecfg_generate', defs);

For more information, seeBuild Support for S-Functions.

Deploy S-Functions for Simulation and Code Generation

You can deploy the S-functionsthat you generate with the Legacy Code Tool so that other people can use them. To deploy an S-function for simulation and code generation, share the following files:

  • Registration file

  • Compiled dynamically loadable executable

  • TLC block file

  • sFunction_makecfg.morrtwmakecfg.mfile

  • Header, source, and include files on which the generated S-function depends

When you use these deployed files:

  • Before using the deployed files in a Simulink model, add the folder that contains the S-function files to the MATLAB®path.

  • If the Legacy Code Tool data structure registers required files as absolute paths and the location of the files changes, regenerate thesFunction_makecfg.morrtwmakecfg.mfile.

Integrate External C++ Objects

The Legacy Code Tool can interface with C++ functions, but not C++ objects. Using the previous example as a starting point, here is an example of how you can work around this limitation.

  • Modify the class definition foradderin a new fileadder_cpp.hpp. Add three new macros that dynamically allocate a newadderobject, invoke the methodadd_one(), and free the memory allocated. Each macro takes a pointer to anadderobject. Because each function called by the Legacy Code Tool must have a C-like signature, the pointer is cached and passed as avoid*. Then you must explicitly cast toadder*in the macro. The new class definition foradder:

    #ifndef _ADDER_CPP_ #define _ADDER_CPP_ class adder { private: int int_state; public: adder(): int_state(0) {}; int add_one(int increment); int get_val() {return int_state;}; }; // Method wrappers implemented as macros #define createAdder(work1) \ *(work1) = new adder #define deleteAdder(work1) \ delete(static_cast(*(work1))) #define adderOutput(work1, u1) \ (static_cast ((work1)))->add_one(u1) #endif /* _ADDER_CPP_ */
  • Updateadder_cpp.cpp. With the class modification, instead of one global instance, each generated S-function manages its ownadderobject.

    #include "adder_cpp.hpp" int adder::add_one(int increment) { int_state += increment; return int_state; }
  • Updatertwdemo_sfun_adder_cpp.cppwith the following changes:

    • StartFcnSpeccalls the macro that allocates a newadderobject and caches the pointer.

      def.StartFcnSpec = 'createAdder(void **work1)';
    • OutputFcnSpeccalls the macro that invokes the methodadd_one()and provides the S-function specificadderpointer object.

      def.OutputFcnSpec = 'int32 y1 = adderOutput(void *work1, int32 u1)';
    • TerminateFcnSpeccalls the macro that frees the memory.

      def.TerminateFcnSpec = 'deleteAdder(void **work1)';

Legacy Code Tool Examples

Integrate External C Functions That Pass Input Arguments By Value Versus Address

This example shows how to use the Legacy Code Tool to integrate legacy C functions that pass their input arguments by value versus address.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototypes of the legacy functions being called in this example are:

  • FLT filterV1(const FLT signal, const FLT prevSignal, const FLT gain)

  • FLT filterV2(const FLT* signal, const FLT prevSignal, const FLT gain)

FLT is a typedef to float. The legacy source code is in the filesyour_types.h,myfilter.h,filterV1.c, andfilterV2.c.

Note the difference in the OutputFcnSpec defined in the two structures; the first case specifies that the first input argument is passed by value, while the second case specifies pass by pointer.

defs = [];% rtwdemo_sfun_filterV1def = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_filterV1'; def.OutputFcnSpec ='single y1 = filterV1(single u1, single u2, single p1)'; def.HeaderFiles = {'myfilter.h'}; def.SourceFiles = {'filterV1.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];% rtwdemo_sfun_filterV2def = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_filterV2'; def.OutputFcnSpec ='single y1 = filterV2(single u1[1], single u2, single p1)'; def.HeaderFiles = {'myfilter.h'}; def.SourceFiles = {'filterV2.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];

Generate S-Functions for Simulation

To generate C-MEX S-functions according to the description provided by the input argument 'defs', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-functions call the legacy functions in simulation. The source code for the S-functions is in the filesrtwdemo_sfun_filterV1.candrtwdemo_sfun_filterV2.c.

legacy_code('sfcn_cmex_generate', defs);

Compile the Generated S-Functions for Simulation

After you generate the C-MEX S-function source files, to compile the S-functions for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', defs);
# # #开始编译rtwdemo_sfun_filterV1墨西哥人(“我/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex19632214', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp02efb0a6_0590_4450_80d2_68d078f139ba', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/filterV1.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_filterV1.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex19632214', '/tmp/Bdoc20b_1465442_59938/tp02efb0a6_0590_4450_80d2_68d078f139ba/filterV1.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_filterV1 ### Exit ### Start Compiling rtwdemo_sfun_filterV2 mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex19632214', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tpfba35956_90bc_4567_9ac1_426335ea8221', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/filterV2.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_filterV2.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex19632214', '/tmp/Bdoc20b_1465442_59938/tpfba35956_90bc_4567_9ac1_426335ea8221/filterV2.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_filterV2 ### Exit

Generate TLC Block Files for Code Generation

After you compile the S-functions and use them in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate TLC block files. Block files specify how the generated code for a model calls the legacy code. If you do not generate TLC block files and you try to generate code for a model that includes the S-functions, code generation fails. The TLC block files for the S-functions arertwdemo_sfun_filterV1.tlcandrtwdemo_sfun_filterV2.tlc.

legacy_code('sfcn_tlc_generate', defs);

Generate an rtwmakecfg.m File for Code Generation

在创建TLC块文件之后,您可以调用the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-functions are not in the same folder as the S-functions, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', defs);

Generate Masked S-Function Blocks for Calling the Generated S-Functions

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate masked S-function blocks that call the S-functions. The software places the blocks in a new model. From there you can copy them to an existing model.

legacy_code('slblock_generate', defs);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_filtershows integration of the model with the legacy code. The subsystem TestFilter serves as a harness for the calls to the legacy C functions via the generate S-functions, with unit delays serving to store the previous output values.

open_system('rtwdemo_lct_filter') open_system('rtwdemo_lct_filter/TestFilter') sim('rtwdemo_lct_filter')

Integrate External C Functions That Pass the Output Argument As a Return Argument

This example shows how to use the Legacy Code Tool to integrate legacy C functions that pass their output as a return argument.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

FLT gainScalar(const FLT in, const FLT gain)

FLT is a typedef to float. The legacy source code is in the filesyour_types.h,gain.h, andgainScalar.c.

% rtwdemo_sfun_gain_scalardef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_gain_scalar'; def.OutputFcnSpec ='single y1 = gainScalar(single u1, single p1)'; def.HeaderFiles = {'gain.h'}; def.SourceFiles = {'gainScalar.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_gain_scalar.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_gain_scalar mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex09148220', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp26fab0e9_aca8_4057_9e23_e3cb99d77f01', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/gainScalar.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_gain_scalar.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex09148220', '/tmp/Bdoc20b_1465442_59938/tp26fab0e9_aca8_4057_9e23_e3cb99d77f01/gainScalar.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_gain_scalar ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_gain_scalar.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_gainshows integration of the model with the legacy code. The subsystem TestGain serves as a harness for the call to the legacy C function via the generate S-function.

open_system('rtwdemo_lct_gain') open_system('rtwdemo_lct_gain/TestGain') sim('rtwdemo_lct_gain')

Integrate External C++ Object Methods

Integrate legacy C++ object methods by using the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C++ MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a block TLC file and optional rtwmakecfg.m file that calls the legacy code during code generation.

Provide 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, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The definition of the legacy C++ class in this example is:

class adder { private: int int_state; public: adder(); int add_one(int increment); int get_val(); };

The legacy source code is in the filesadder_cpp.handadder_cpp.cpp.

% rtwdemo_sfun_adder_cppdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_adder_cpp'; def.StartFcnSpec ='createAdder()'; def.OutputFcnSpec ='int32 y1 = adderOutput(int32 u1)'; def.TerminateFcnSpec ='deleteAdder()'; def.HeaderFiles = {'adder_cpp.h'}; def.SourceFiles = {'adder_cpp.cpp'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; def.Options.language ='C++'; def.Options.useTlcWithAccel = false;

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_adder_cpp.cpp.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_adder_cpp mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_60413/tp02da355b/ex06428671', '-c', '-outdir', '/tmp/Bdoc20b_1465442_60413/tp517bc881_295f_4182_9278_c25a3baed708', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/adder_cpp.cpp') Building with 'g++'. MEX completed successfully. mex('rtwdemo_sfun_adder_cpp.cpp', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_60413/tp02da355b/ex06428671', '-cxx', '/tmp/Bdoc20b_1465442_60413/tp517bc881_295f_4182_9278_c25a3baed708/adder_cpp.o') Building with 'g++'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_adder_cpp ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again. Set the first input to 'sfcn_tlc_generate' to generate a TLC block file that supports code generation through Simulink® Coder™. If the TLC block file is not created and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_adder_cpp.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again. Set the first input to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file that supports code generation through Simulink® Coder™. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again. Set the first input to 'slblock_generate' to generate a masked S-function block that is configured to call that S-function. The software places the block in a new model. You can copy the block to an existing model.

% legacy_code('slblock_generate', def);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_cppshows integration with the legacy code.

open_system('rtwdemo_lct_cpp') sim('rtwdemo_lct_cpp')

Integrate External C Functions That Pass Input and Output Arguments as Parameters with a Fixed-Point Data Type

Integrate legacy C functions that pass their inputs and outputs by using parameters of a fixed-point data type with the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

myFixpt timesS16(const myFixpt in1, const myFixpt in2, const uint8_T fracLength)

myFixpt is logically a fixed point data type, which is physically a typedef to a 16-bit integer:

myFixpt = Simulink.NumericType; myFixpt.DataTypeMode ='Fixed-point: binary point scaling'; myFixpt.Signed = true; myFixpt.WordLength = 16; myFixpt.FractionLength = 10; myFixpt.IsAlias = true; myFixpt.HeaderFile ='timesFixpt.h';

The legacy source code is in the filestimesFixpt.h, andtimesS16.c.

% rtwdemo_sfun_gain_fixptdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_gain_fixpt'; def.OutputFcnSpec ='myFixpt y1 = timesS16(myFixpt u1, myFixpt p1, uint8 p2)'; def.HeaderFiles = {'timesFixpt.h'}; def.SourceFiles = {'timesS16.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_gain_fixpt.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
# # #开始编译rtwdemo_sfun_gain_fixpt墨西哥人(' -I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex05928773', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp644ad607_18ab_4194_b113_c281e4a6b524', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/timesS16.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_gain_fixpt.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex05928773', '/tmp/Bdoc20b_1465442_59938/tp644ad607_18ab_4194_b113_c281e4a6b524/timesS16.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_gain_fixpt ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again. Set the first input to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_gain_fixpt.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again. Set the first input to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file that supports code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again. Set the first input to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. You can copy the block to an existing model.

legacy_code('slblock_generate', def);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_fixpt_paramsshows integration of the model with the legacy code. The subsystem TestFixpt serves as a harness for the call to the legacy C function via the generated S-function.

open_system('rtwdemo_lct_fixpt_params') open_system('rtwdemo_lct_fixpt_params/TestFixpt') sim('rtwdemo_lct_fixpt_params')

Integrate External C Functions That Pass Input and Output Arguments as Signals with a Fixed-Point Data Type

This example shows how to use the Legacy Code Tool to integrate legacy C functions that pass their inputs and outputs by using parameters of fixed-point data type.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

myFixpt timesS16(const myFixpt in1, const myFixpt in2, const uint8_T fracLength)

myFixpt is logically a fixed-point data type, which is physically a typedef to a 16-bit integer:

myFixpt = Simulink.NumericType; myFixpt.DataTypeMode ='Fixed-point: binary point scaling'; myFixpt.Signed = true; myFixpt.WordLength = 16; myFixpt.FractionLength = 10; myFixpt.IsAlias = true; myFixpt.HeaderFile ='timesFixpt.h';

The legacy source code is in the filestimesFixpt.h, andtimesS16.c.

% rtwdemo_sfun_times_s16def = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_times_s16'; def.OutputFcnSpec ='myFixpt y1 = timesS16(myFixpt u1, myFixpt u2, uint8 p1)'; def.HeaderFiles = {'timesFixpt.h'}; def.SourceFiles = {'timesS16.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_times_s16.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_times_s16 mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex96454812', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tpfeed7570_b6a2_4dda_9ed9_f9be620d2fa9', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/timesS16.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_times_s16.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex96454812', '/tmp/Bdoc20b_1465442_59938/tpfeed7570_b6a2_4dda_9ed9_f9be620d2fa9/timesS16.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_times_s16 ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_times_s16.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Show the Integration of the Model with Legacy Code

The modelrtwdemo_lct_fixpt_signalsshows integration of the model with the legacy code. The subsystem TestFixpt serves as a harness for the call to the legacy C function via the generated S-function.

open_system('rtwdemo_lct_fixpt_signals') open_system('rtwdemo_lct_fixpt_signals/TestFixpt') sim('rtwdemo_lct_fixpt_signals')

Integrate External C Functions with Instance-Specific Persistent Memory

Integrate legacy C functions that use instance-specific persistent memory by using the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototypes of the legacy functions being called in this example are:

void memory_bus_init(COUNTERBUS *mem, int32_T upper_sat, int32_T lower_sat);

void memory_bus_step(COUNTERBUS *input, COUNTERBUS *mem, COUNTERBUS *output);

mem is an instance-specific persistent memory for applying a one integration step delay. COUNTERBUS is a struct typedef defined incounterbus.hand implemented with a Simulink.Bus object in the base workspace. The legacy source code is in the filesmemory_bus.h, andmemory_bus.c.

evalin('base','load rtwdemo_lct_data.mat')% rtwdemo_sfun_workdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_work'; def.InitializeConditionsFcnSpec =...'void memory_bus_init(COUNTERBUS work1[1], int32 p1, int32 p2)'; def.OutputFcnSpec =...“空白memory_bus_step (COUNTERBUS COUNTERBUS u1 [1]work1[1], COUNTERBUS y1[1])'; def.HeaderFiles = {'memory_bus.h'}; def.SourceFiles = {'memory_bus.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_work.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_work mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex38707886', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp1d9f1305_b2ae_4295_8ed0_4ed5967afc8b', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/memory_bus.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_work.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex38707886', '/tmp/Bdoc20b_1465442_59938/tp1d9f1305_b2ae_4295_8ed0_4ed5967afc8b/memory_bus.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_work ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_work.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Show the Integration of the Model with Legacy Code

The modelrtwdemo_lct_workshows integration of the model with the legacy code. The subsystem memory_bus serves as a harness for the call to the legacy C function.

open_system('rtwdemo_lct_work') open_system('rtwdemo_lct_work/memory_bus') sim('rtwdemo_lct_work')

Integrate External C Functions That Use Structure Arguments

Integrate legacy C functions with structure arguments that use Simulink® buses with the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

counterbusFcn(COUNTERBUS *u1, int32_T u2, COUNTERBUS *y1, int32_T *y2)

COUNTERBUS is a struct typedef defined incounterbus.hand implemented with a Simulink.Bus object in the base workspace. The legacy source code is in the filescounterbus.h, andcounterbus.c.

evalin('base','load rtwdemo_lct_data.mat')% rtwdemo_sfun_counterbusdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_counterbus'; def.OutputFcnSpec =...'void counterbusFcn(COUNTERBUS u1[1], int32 u2, COUNTERBUS y1[1], int32 y2[1])'; def.HeaderFiles = {'counterbus.h'}; def.SourceFiles = {'counterbus.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_counterbus.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_counterbus mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex90330074', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp88a0b857_3a1a_42fe_bfde_4dfa484637a0', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/counterbus.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_counterbus.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex90330074', '/tmp/Bdoc20b_1465442_59938/tp88a0b857_3a1a_42fe_bfde_4dfa484637a0/counterbus.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_counterbus ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_counterbus.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Show the Integration of the Model with Legacy Code

The modelrtwdemo_lct_busshows integration of the model with the legacy code. The subsystem TestCounter serves as a harness for the call to the legacy C function.

open_system('rtwdemo_lct_bus') open_system('rtwdemo_lct_bus/TestCounter') sim('rtwdemo_lct_bus')

Integrate External C Functions That Pass Input and Output Arguments as Signals with Complex Data

Integrate legacy C functions using complex signals with the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

void cplx_gain(creal_T *input, creal_T *gain, creal_T *output);

creal_T is the complex representation of a double. The legacy source code is in the filescplxgain.h, andcplxgain.c.

% rtwdemo_sfun_gain_scalardef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_cplx_gain'; def.OutputFcnSpec =...['void cplx_gain(complex u1[1], '...'complex p1[1], complex y1[1])']; def.HeaderFiles = {'cplxgain.h'}; def.SourceFiles = {'cplxgain.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_cplx_gain.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_cplx_gain mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex97344681', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp1dd24d36_0084_42a3_8810_2e34ae9e5dea', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/cplxgain.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_cplx_gain.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex97344681', '/tmp/Bdoc20b_1465442_59938/tp1dd24d36_0084_42a3_8810_2e34ae9e5dea/cplxgain.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_cplx_gain ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_cplx_gain.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Show the Integration of the Model with Legacy Code

The modelrtwdemo_lct_cplxgainshows integration of the model with the legacy code. The subsystem complex_gain serves as a harness for the call to the legacy C function via the generate S-function.

ifisempty(find_system('SearchDepth',0,'Name','rtwdemo_lct_cplxgain')) open_system('rtwdemo_lct_cplxgain') open_system('rtwdemo_lct_cplxgain/complex_gain') sim('rtwdemo_lct_cplxgain')end

Integrate External C Functions That Pass Arguments That Have Inherited Dimensions

This example shows how to use the Legacy Code Tool to integrate legacy C functions whose arguments have inherited dimensions.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototypes of the legacy functions being called in this example are:

  • void mat_add(real_T *u1, real_T *u2, int32_T nbRows, int32_T nbCols, real_T *y1)

  • void mat_mult(real_T *u1, real_T *u2, int32_T nbRows1, int32_T nbCols1, int32_T nbCols2, real_T *y1)

real_T is a typedef to double, and int32_T is a typedef to a 32-bit integer. The legacy source code is in the filesmat_ops.h, andmat_ops.c.

defs = [];% rtwdemo_sfun_mat_adddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_mat_add'; def.OutputFcnSpec = ['void mat_add(double u1[][], double u2[][], '...'int32 u3, int32 u4, double y1[size(u1,1)][size(u1,2)])']; def.HeaderFiles = {'mat_ops.h'}; def.SourceFiles = {'mat_ops.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];% rtwdemo_sfun_mat_multdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_mat_mult'; def.OutputFcnSpec = ['void mat_mult(double u1[p1][p2], double u2[p2][p3], '...'int32 p1, int32 p2, int32 p3, double y1[p1][p3])']; def.HeaderFiles = {'mat_ops.h'}; def.SourceFiles = {'mat_ops.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];

Generate S-Functions for Simulation

To generate C-MEX S-functions according to the description provided by the input argument 'defs', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-functions call the legacy functions during simulation. The source code for the S-function is in the filesrtwdemo_sfun_mat_add.candrtwdemo_sfun_mat_mult.c.

legacy_code('sfcn_cmex_generate', defs);

Compile the Generated S-Functions for Simulation

After you generate the C-MEX S-function source files, to compile the S-functions for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', defs);
### Start Compiling rtwdemo_sfun_mat_add mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex89794148', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp6b8a7cec_1174_4c44_adfc_ea1bc26c0e4d', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/mat_ops.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_mat_add.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex89794148', '/tmp/Bdoc20b_1465442_59938/tp6b8a7cec_1174_4c44_adfc_ea1bc26c0e4d/mat_ops.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_mat_add ### Exit ### Start Compiling rtwdemo_sfun_mat_mult mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex89794148', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tpb31b9957_2204_43e5_98de_07ed4700ce46', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/mat_ops.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_mat_mult.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex89794148', '/tmp/Bdoc20b_1465442_59938/tpb31b9957_2204_43e5_98de_07ed4700ce46/mat_ops.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_mat_mult ### Exit

Generate TLC Block Files for Code Generation

After you compile the S-functions and use them in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate TLC block files. Block files specify how the generated code for a model calls the legacy code. If you do not generate TLC block files and you try to generate code for a model that includes the S-functions, code generation fails. The TLC block files for the S-functions arertwdemo_sfun_mat_add.tlcandrtwdemo_sfun_mat_mult.tlc.

legacy_code('sfcn_tlc_generate', defs);

Generate an rtwmakecfg.m File for Code Generation

在创建TLC块文件之后,您可以调用the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-functions are not in the same folder as the S-functions, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', defs);

Generate Masked S-Function Blocks for Calling the Generated S-Functions

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate masked S-function blocks that call the S-functions. The software places the blocks in a new model. From there you can copy them to an existing model

legacy_code('slblock_generate', defs);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_inherit_dimsshows integration of the model with the legacy code. The subsystem TestMatOps serves as a harness for the calls to the legacy C functions, with unit delays serving to store the previous output values.

open_system('rtwdemo_lct_inherit_dims') open_system('rtwdemo_lct_inherit_dims/TestMatOps') sim('rtwdemo_lct_inherit_dims')

Integrate External C Functions That Pass Arguments as Multi-Dimensional Signals

This example shows how to use the Legacy Code Tool to integrate legacy C functions with multi-dimensional Signals.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

void array3d_add(real_T *y1, real_T *u1, real_T *u2, int32_T nbRows, int32_T nbCols, int32_T nbPages);

real_T is a typedef to double, and int32_T is a typedef to a 32-bit integer. The legacy source code is in the filesndarray_ops.h, andndarray_ops.c.

% rtwdemo_sfun_ndarray_adddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_ndarray_add'; def.OutputFcnSpec =...['void array3d_add(double y1[size(u1,1)][size(u1,2)][size(u1,3)], ',...'double u1[][][], double u2[][][], '...'int32 size(u1,1), int32 size(u1,2), int32 size(u1,3))']; def.HeaderFiles = {'ndarray_ops.h'}; def.SourceFiles = {'ndarray_ops.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

y1 is a 3-D output signal of same dimensions as the 3-D input signal u1. Note that the last 3 arguments passed to the legacy function correspond to the number of element in each dimension of the 3-D input signal u1.

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_ndarray_add.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_ndarray_add mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex14927435', '-c', '-outdir', '/tmp/Bdoc20b_1465442_50501/tpd03f25b7_ed71_4ebc_9757_a9987b30fce3', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/ndarray_ops.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_ndarray_add.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex14927435', '/tmp/Bdoc20b_1465442_50501/tpd03f25b7_ed71_4ebc_9757_a9987b30fce3/ndarray_ops.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_ndarray_add ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_ndarray_add.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Showing the Generated Integration with Legacy Code

The modelrtwdemo_lct_ndarrayshows integration of the model with the legacy code. The subsystem ndarray_add serves as a harness for the call to the legacy C function.

open_system('rtwdemo_lct_ndarray') open_system('rtwdemo_lct_ndarray/ndarray_add') sim('rtwdemo_lct_ndarray')

Integrate External C Functions That Implement Start and Terminate Actions

Integrate legacy C functions that have start and terminate actions by using the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). 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)

The legacy source code is in the filesyour_types.h,fault.h, andfault.c.

% rtwdemo_sfun_faultdef = legacy_code('initialize');def.SFunctionName ='rtwdemo_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 = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; def.Options.useTlcWithAccel = false;

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_fault.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_fault mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex46254423', '-c', '-outdir', '/tmp/Bdoc20b_1465442_50501/tp48618372_776a_4afe_8b3a_e2584433cfd0', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/fault.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_fault.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex46254423', '/tmp/Bdoc20b_1465442_50501/tp48618372_776a_4afe_8b3a_e2584433cfd0/fault.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_fault ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_fault.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Showing the Generated Integration with Legacy Code

The modelrtwdemo_lct_start_termshows integration of the model 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('rtwdemo_lct_start_term') open_system('rtwdemo_lct_start_term/TestFault') sim('rtwdemo_lct_start_term')

Integrate External C Functions That Implement N-Dimensional Table Lookups

Integrate legacy C functions that implement N-dimensional table lookups by using the Legacy Code Tool.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

FLT directLookupTableND(const FLT *tableND, const UINT32 nbDims, const UINT32 *tableDims, const UINT32 *tableIdx)

FLT is a typedef to float, and UINT32 is a typedef to unsigned int32. The legacy source code is in the filesyour_types.h,lookupTable.h, anddirectLookupTableND.c.

defs = []; evalin('base','load rtwdemo_lct_data.mat')% rtwdemo_sfun_dlut3Ddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_dlut3D'; def.OutputFcnSpec ='single y1 = DirectLookupTable3D(single p1[][][], uint32 p2[3], uint32 u1[3])'; def.HeaderFiles = {'lookupTable.h'}; def.SourceFiles = {'directLookupTableND.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];% rtwdemo_sfun_dlut4Ddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_dlut4D'; def.OutputFcnSpec ='single y1 = DirectLookupTable4D(single p1[][][][], uint32 p2[4], uint32 u1[4])'; def.HeaderFiles = {'lookupTable.h'}; def.SourceFiles = {'directLookupTableND.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];

Generate S-Functions for Simulation

To generate C-MEX S-functions according to the description provided by the input argument 'defs', call the function legacy_code() again. Set the first input to 'sfcn_cmex_generate'. The S-functions call the legacy functions during simulation. The source code for the S-functions is in the filesrtwdemo_sfun_dlut3D.candrtwdemo_sfun_dlut4D.c.

legacy_code('sfcn_cmex_generate', defs);

Compile the Generated S-Functions for Simulation

After you generate the C-MEX S-function source files, to compile the S-functions for simulation with Simulink®, call the function legacy_code() again. Set the first input to 'compile'.

legacy_code('compile', defs);
### Start Compiling rtwdemo_sfun_dlut3D mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex19426386', '-c', '-outdir', '/tmp/Bdoc20b_1465442_50501/tpc801ab37_411a_443d_9cae_c78fff19e554', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/directLookupTableND.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_dlut3D.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex19426386', '/tmp/Bdoc20b_1465442_50501/tpc801ab37_411a_443d_9cae_c78fff19e554/directLookupTableND.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_dlut3D ### Exit ### Start Compiling rtwdemo_sfun_dlut4D mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex19426386', '-c', '-outdir', '/tmp/Bdoc20b_1465442_50501/tp50e2bd81_d9d6_485f_93e3_cc7c7dc64f16', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/directLookupTableND.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_dlut4D.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex19426386', '/tmp/Bdoc20b_1465442_50501/tp50e2bd81_d9d6_485f_93e3_cc7c7dc64f16/directLookupTableND.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_dlut4D ### Exit

Generate TLC Block Files for Code Generation

After you compile the S-functions and use them in simulation, you can call the function legacy_code() again. Set the first input to 'sfcn_tlc_generate' to generate TLC block files. Block files specify how the generated code for a model calls the legacy code. If you do not generate TLC block files and you try to generate code for a model that includes the S-functions, code generation fails. The TLC block files for the S-functions arertwdemo_sfun_dlut3D.tlcandrtwdemo_sfun_dlut4D.tlc.

legacy_code('sfcn_tlc_generate', defs);

Generate an rtwmakecfg.m File for Code Generation

在创建TLC块文件之后,您可以调用the function legacy_code() again. Set the first input to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-functions are not in the same folder as the S-functions, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', defs);

Generate Masked S-Function Blocks for Calling the Generated S-Functions

后编译C-MEX s函数源,你can call the function legacy_code() again. Set the first input to 'slblock_generate' to generate masked S-function blocks that call the S-functions. The software places the blocks in a new model. You can copy the blocks to an existing model.

legacy_code('slblock_generate', defs);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_lutshows integration of the model with the legacy code. The subsystem TestFixpt serves as a harness for the call to the legacy C function, and the Display blocks compare the output of the function with the output of the built-in Simulink® lookup blocks. The results are identical.

open_system('rtwdemo_lct_lut') open_system('rtwdemo_lct_lut/TestLut1') sim('rtwdemo_lct_lut')

Integrate External C Functions That Pass Arguments as Multi-Dimensional Signals

This example shows how to use the Legacy Code Tool to integrate legacy C functions with multi-dimensional Signals.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

void array3d_add(real_T *y1, real_T *u1, real_T *u2, int32_T nbRows, int32_T nbCols, int32_T nbPages);

real_T is a typedef to double, and int32_T is a typedef to a 32-bit integer. The legacy source code is in the filesndarray_ops.h, andndarray_ops.c.

% rtwdemo_sfun_ndarray_adddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_ndarray_add'; def.OutputFcnSpec =...['void array3d_add(double y1[size(u1,1)][size(u1,2)][size(u1,3)], ',...'double u1[][][], double u2[][][], '...'int32 size(u1,1), int32 size(u1,2), int32 size(u1,3))']; def.HeaderFiles = {'ndarray_ops.h'}; def.SourceFiles = {'ndarray_ops.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'};

y1 is a 3-D output signal of same dimensions as the 3-D input signal u1. Note that the last 3 arguments passed to the legacy function correspond to the number of element in each dimension of the 3-D input signal u1.

Generate an S-Function for Simulation

To generate a C-MEX S-function according to the description provided by the input argument 'def', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-function calls the legacy functions during simulation. The source code for the S-function is in the filertwdemo_sfun_ndarray_add.c.

legacy_code('sfcn_cmex_generate', def);

Compile the Generated S-Function for Simulation

After you generate the C-MEX S-function source file, to compile the S-function for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', def);
### Start Compiling rtwdemo_sfun_ndarray_add mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex14927435', '-c', '-outdir', '/tmp/Bdoc20b_1465442_50501/tpd03f25b7_ed71_4ebc_9757_a9987b30fce3', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/ndarray_ops.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_ndarray_add.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_50501/tpa56c3ced/ex14927435', '/tmp/Bdoc20b_1465442_50501/tpd03f25b7_ed71_4ebc_9757_a9987b30fce3/ndarray_ops.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_ndarray_add ### Exit

Generate a TLC Block File for Code Generation

After you compile the S-function and use it in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate a TLC block file. The block file specifies how the generated code for a model calls the legacy code. If you do not generate a TLC block file and you try to generate code for a model that includes the S-function, code generation fails. The TLC block file for the S-function is:rtwdemo_sfun_ndarray_add.tlc.

legacy_code('sfcn_tlc_generate', def);

Generate an rtwmakecfg.m File for Code Generation

After you create the TLC block file, you can call the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-function are not in the same folder as the S-function, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', def);

Generate a Masked S-Function Block for Calling the Generated S-Function

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate a masked S-function block that calls that S-function. The software places the block in a new model. From there you can copy it to an existing model.

legacy_code('slblock_generate', def);

Showing the Generated Integration with Legacy Code

The modelrtwdemo_lct_ndarrayshows integration of the model with the legacy code. The subsystem ndarray_add serves as a harness for the call to the legacy C function.

open_system('rtwdemo_lct_ndarray') open_system('rtwdemo_lct_ndarray/ndarray_add') sim('rtwdemo_lct_ndarray')

Integrate External C Functions with a Block Sample Time Specified, Inherited, and Parameterized

This example shows how to use the Legacy Code Tool to integrate legacy C functions with the block's sample time specified, inherited and parameterized.

With the Legacy Code Tool, you can:

  • Provide the legacy function specification.

  • Generate a C-MEX S-function that calls the legacy code during simulation.

  • Compile and build the generated S-function for simulation.

  • Generate a TLC block file and optional rtwmakecfg.m file that specifies how the generated code for a model calls the legacy code.

Provide the Legacy Function Specification

Legacy Code Tool functions take a specific data structure or array of structures as the argument. You can initialize the data structure by calling the function legacy_code() using 'initialize' as the first input. After initializing the structure, assign its properties to values corresponding to the legacy code being integrated. For detailed help on the properties, calllegacy_code('help'). The prototype of the legacy functions being called in this example is:

FLT gainScalar(const FLT in, const FLT gain)

FLT is a typedef to float. The legacy source code is in the filesyour_types.h,gain.h, andgainScalar.c.

defs = [];% rtwdemo_sfun_st_inheriteddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_st_inherited'; def.OutputFcnSpec ='single y1 = gainScalar(single u1, single p1)'; def.HeaderFiles = {'gain.h'}; def.SourceFiles = {'gainScalar.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];% rtwdemo_sfun_st_fixeddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_st_fixed'; def.OutputFcnSpec ='single y1 = gainScalar(single u1, single p1)'; def.HeaderFiles = {'gain.h'}; def.SourceFiles = {'gainScalar.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; def.SampleTime = [2 1]; defs = [defs; def];% rtwdemo_sfun_st_parameterizeddef = legacy_code('initialize');def.SFunctionName ='rtwdemo_sfun_st_parameterized'; def.OutputFcnSpec ='single y1 = gainScalar(single u1, single p1)'; def.HeaderFiles = {'gain.h'}; def.SourceFiles = {'gainScalar.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; def.SampleTime ='parameterized'; defs = [defs; def];

Generate S-Functions for Simulation

To generate C-MEX S-functions according to the description provided by the input argument 'defs', call the function legacy_code() again with the first input set to 'sfcn_cmex_generate'. The S-functions call the legacy functions during simulation. The source code for the S-functions is in the filesrtwdemo_sfun_st_inherited.candrtwdemo_sfun_st_fixed.c.rtwdemo_sfun_st_parameterized.c.

legacy_code('sfcn_cmex_generate', defs);

Compile the Generated S-Functions for Simulation

After you generate the C-MEX S-function source files, to compile the S-functions for simulation with Simulink®, call the function legacy_code() again with the first input set to 'compile'.

legacy_code('compile', defs);
# # #开始编译rtwdemo_sfun_st_inherited墨西哥人('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tpabcf5c2d_60af_4daf_adc8_612f6a269082', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/gainScalar.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_st_inherited.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '/tmp/Bdoc20b_1465442_59938/tpabcf5c2d_60af_4daf_adc8_612f6a269082/gainScalar.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_st_inherited ### Exit ### Start Compiling rtwdemo_sfun_st_fixed mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tp04d8c1e7_032f_4a10_9ce3_e13bd3d5e3dd', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/gainScalar.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_st_fixed.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '/tmp/Bdoc20b_1465442_59938/tp04d8c1e7_032f_4a10_9ce3_e13bd3d5e3dd/gainScalar.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_st_fixed ### Exit ### Start Compiling rtwdemo_sfun_st_parameterized mex('-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '-c', '-outdir', '/tmp/Bdoc20b_1465442_59938/tpa80f921e_bbba_428b_82df_20ed6254c645', '/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/gainScalar.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_st_parameterized.c', '-I/mathworks/devel/bat/Bdoc20b/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc20b_1465442_59938/tp8eb0d42c/ex74504488', '/tmp/Bdoc20b_1465442_59938/tpa80f921e_bbba_428b_82df_20ed6254c645/gainScalar.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_st_parameterized ### Exit

Generate TLC Block Files for Code Generation

After you compile the S-functions and use them in simulation, you can call the function legacy_code() again with the first input set to 'sfcn_tlc_generate' to generate TLC block files. Block files specify how the generated code for a model calls the legacy code. If you do not generate TLC block files and you try to generate code for a model that includes the S-functions, code generation fails. The TLC block files for the S-functions arertwdemo_sfun_st_inherited.tlcandrtwdemo_sfun_st_fixed.tlc.rtwdemo_sfun_st_parameterized.tlc.

legacy_code('sfcn_tlc_generate', defs);

Generate an rtwmakecfg.m File for Code Generation

在创建TLC块文件之后,您可以调用the function legacy_code() again with the first input set to 'rtwmakecfg_generate' to generate an rtwmakecfg.m file to support code generation. If the required source and header files for the S-functions are not in the same folder as the S-functions, and you want to add these dependencies in the makefile produced during code generation, generate the rtwmakecfg.m file.

legacy_code('rtwmakecfg_generate', defs);

Generate Masked S-Function Blocks for Calling the Generated S-Functions

后编译C-MEX s函数源,你can call the function legacy_code() again with the first input set to 'slblock_generate' to generate masked S-function blocks that call the S-functions. The software places the blocks in a new model. From there you can copy them to an existing model.

legacy_code('slblock_generate', defs);

Show the Generated Integration with Legacy Code

The modelrtwdemo_lct_sampletimeshows integration of the model with the legacy code. The subsystem sample_time serves as a harness for the calls to the legacy C functions, with unit delays serving to store the previous output values.

open_system('rtwdemo_lct_sampletime') open_system('rtwdemo_lct_sampletime/sample_time') sim('rtwdemo_lct_sampletime')

See Also

Related Topics