主要内容

使用遗留代码工具将对外部代码的调用导入生成的代码中

遗留代码工具和代码生成

你可以使用Simulink金宝app®遗留代码工具为遗留或自定义代码生成完全内联的C MEX s -函数。s函数针对嵌入式组件(如设备驱动程序和查找表)进行了优化,它们调用现有的C或c++函数。

请注意

遗留代码工具可以与c++函数交互,但不能与c++对象交互。要解决此问题,以便该工具可以与c++对象进行接口,请参见遗留代码工具限制

您可以使用该工具:

  • 编译并构建生成的s函数进行仿真。

  • 生成一个屏蔽的S-Function块配置为调用现有外部代码。

如果您想在您打算为其生成代码的模型中包含这些类型的s函数,请使用该工具生成一个TLC块文件。TLC块文件指定为模型生成的代码如何调用现有的C或c++函数。

如果S-function依赖于包含S-function动态加载可执行文件的文件夹以外的其他文件夹中的文件,请使用工具生成一个S-function动态加载可执行文件sFunction_makecfg.mrtwmakecfg.m文件为s函数。当您构建包含s函数的模型时,生成文件将维护这些依赖关系。例如,对于某些应用程序(如自定义目标),您可能希望将文件定位到特定于目标的位置。构建过程寻找sFunction_makecfg.mrtwmakecfg.m在与s函数动态加载可执行文件相同的文件夹中,并调用文件中的函数。

有关更多信息,请参见使用遗留代码工具集成C函数

生成代码生成的内联s函数文件

根据应用程序的代码生成需求,要为使用s函数的模型生成代码,请执行以下任意一种操作:

  • 生成一个. cpp文件为内联s函数。在“遗留代码工具”数据结构中,设置Options.singleCPPMexFile字段真正的在从现有的C函数生成s函数源文件之前。例如:

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

  • 为内联s函数生成一个源文件和一个TLC块文件。例如:

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

singleCPPMexFile局限性

您不能设置singleCPPMexFile字段真正的如果

  • Options.language =“c++”

  • 控件使用下列Simulink对象之一金宝appIsAlias属性设置为真正的

    • 金宝app仿真软件。公共汽车

    • 金宝app仿真软件。AliasType

    • 金宝app仿真软件。NumericType

  • 遗留代码工具功能规范包括void *void * *表示状态参数的标量功数据

  • HeaderFiles“遗留代码工具”结构的字段指定多个头文件

将代码样式设置应用于遗留函数

将代码样式的模型配置参数应用到遗留函数:

  1. 初始化遗留代码工具数据结构。例如:

    Def = legacy_code('初始化');
  2. 的值Options.singleCPPMexFile字段真正的.例如:

    def.Options.singleCPPMexFile = true;

检查设置,输入:

def.Options.singleCPPMexFile

singleCPPMexFile局限性

您不能设置singleCPPMexFile字段真正的如果

  • Options.language =“c++”

  • 控件使用下列Simulink对象之一金宝appIsAlias属性设置为真正的

    • 金宝app仿真软件。公共汽车

    • 金宝app仿真软件。AliasType

    • 金宝app仿真软件。NumericType

  • 遗留代码工具功能规范包括void *void * *表示状态参数的标量功数据

  • HeaderFiles“遗留代码工具”结构的字段指定多个头文件

地址依赖文件在不同的位置

默认情况下,遗留代码工具假定s -函数所依赖的文件与s -函数的动态可加载可执行文件位于同一文件夹中。如果您的s函数依赖于驻留在其他地方的文件,并且您正在使用模板makefile构建过程,则生成一个sFunction_makecfg.mrtwmakecfg.m文件对于s函数。例如,如果遗留代码工具数据结构将编译资源定义为路径名,则可以生成此文件。

要生成sFunction_makecfg.mrtwmakecfg.m文件,调用legacy_code函数与“sfcn_makecfg_generate”“rtwmakecfg_generate”作为第一个参数,遗留代码工具数据结构的名称作为第二个参数。例如:

legacy_code (sfcn_makecfg_generate, lct_spec);

如果您在同一个文件夹中使用多个注册文件,并为每个文件生成s函数,只需调用一次legacy_code,呼叫legacy_code指定“sfcn_makecfg_generate”“rtwmakecfg_generate”必须对所有注册文件通用。有关更多信息,请参见处理多个注册文件

例如,如果你定义def作为遗留代码工具结构的数组,您调用legacy_code“sfcn_makecfg_generate”一次。

Defs = [defs1(:);defs2(:);defs3(:)];legacy_code (sfcn_makecfg_generate, def);

有关更多信息,请参见构建对s -金宝app函数的支持

为模拟和代码生成部署s -函数

你可以部署s函数您使用遗留代码工具生成的代码,以便其他人可以使用它们。要部署s函数进行模拟和代码生成,请共享以下文件:

  • 注册文件

  • 编译动态加载的可执行文件

  • TLC块文件

  • sFunction_makecfg.mrtwmakecfg.m文件

  • 生成的s -函数所依赖的头文件、源文件和包含文件

当你使用这些部署文件时:

  • 在使用Simulink模型中部署的文件之前,请将包含s函数文件的文件夹添加金宝app到MATLAB中®路径。

  • 如果遗留代码工具数据结构将所需的文件注册为绝对路径,并且文件的位置发生更改,则重新生成sFunction_makecfg.mrtwmakecfg.m文件。

集成外部c++对象

遗留代码工具可以与c++函数交互,但不能与c++对象交互。以前面的示例为起点,下面是一个示例,说明如何绕过这个限制。

  • 的类定义加法器在一个新文件中adder_cpp.hpp.添加三个新的宏,动态分配一个新的宏加法器对象,调用该方法add_one (),并释放已分配的内存。对象的指针加法器对象。由于遗留代码工具调用的每个函数都必须具有类似c的签名,因此指针被缓存并作为void *.然后必须显式转换为加法器*在宏中。的新类定义加法器

    #ifndef _ADDER_CPP_ #定义_ADDER_CPP_类加法器{private: int int_state;Public: adder(): int_state(0) {};Int add_one(Int increment);Int get_val(){返回int_state;};//实现为宏的方法包装器#define createAdder(work1) \ *(work1) =新加器#define deleteAdder(work1) \ delete(static_cast<加器*>(*(work1))) #define adderOutput(work1, u1) \ (static_cast<加器*>((work1)))->add_one(u1) #endif /* _ADDER_CPP_ */
  • 更新adder_cpp.cpp.通过类修改,每个生成的s函数都管理自己的实例,而不是一个全局实例加法器对象。

    #include " adder_cppp .hpp" int加器::add_one(int增量){int_state +=增量;返回int_state;}
  • 更新rtwdemo_sfun_adder_cpp.cpp改动如下:

    • StartFcnSpec调用分配new加法器对象并缓存指针。

      def.StartFcnSpec = 'createAdder(void **work1)';
    • OutputFcnSpec调用调用该方法的宏add_one ()并提供特定的s函数加法器对象的指针。

      def.OutputFcnSpec = 'int32 y1 = adderOutput(void *work1, int32 u1)';
    • TerminateFcnSpec调用释放内存的宏。

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

另请参阅

相关的话题