Import Calls to External Code into Generated Code with Legacy Code Tool - MATLAB & Simulink (original) (raw)

Legacy Code Tool and Code Generation

You can use the SimulinkĀ® Legacy Code Tool to 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, see Legacy Code Tool Limitations.

You can use the tool to:

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 an sFunction_makecfg.m or rtwmakecfg.m file 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 for sFunction_makecfg.m or rtwmakecfg.m in the same folder as the S-function dynamically loadable executable and calls the function in the file.

For more information, see Integrate 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:

singleCPPMexFile Limitations

You cannot set the singleCPPMexFile field to true if

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 the Options.singleCPPMexFile field to true. For example:
    def.Options.singleCPPMexFile = true;

To check the setting, enter:

def.Options.singleCPPMexFile

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 an sFunction_makecfg.m or rtwmakecfg.m file for 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 the sFunction_makecfg.m or rtwmakecfg.m file, call the legacy_code function 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 to legacy_code, the call tolegacy_code that specifies'sfcn_makecfg_generate' or'rtwmakecfg_generate' must be common to all registration files. For more information, see Handling Multiple Registration Files.

For example, if you define defs as an array of Legacy Code Tool structures, you call legacy_code with 'sfcn_makecfg_generate' once.

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

For more information, see Build Support for S-Functions.

Deploy S-Functions for Simulation and Code Generation

You can deploy the S-functions that 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:

When you use these deployed files:

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.

#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<adder*>(
(work1)))
#define adderOutput(work1, u1) \
(static_cast<adder*> ((work1)))->add_one(u1)
#endif /* ADDER_CPP */

#include "adder_cpp.hpp"
int adder::add_one(int increment)
{
int_state += increment;
return int_state;
}

See Also

legacy_code

Topics