主要内容

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

遗留代码工具和代码生成

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

请注意

遗留代码工具可以与c++函数交互,但不能与c++对象交互。要解决这个问题,以便该工具能够与c++对象交互,请参见遗留代码工具的限制

您可以使用该工具:

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

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

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

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

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

为代码生成生成内联的S-Function文件

根据应用程序的代码生成需求,为使用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对象之一IsAlias属性设置为真正的

    • 仿真软件。公共汽车

    • 仿真软件。AliasType

    • 仿真软件。NumericType

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

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

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

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

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

    Def = legacy_code('初始化');
  2. 在数据结构中设置Options.singleCPPMexFile字段真正的.例如:

    def.Options.singleCPPMexFile = true;

要检查设置,输入:

def.Options.singleCPPMexFile

singleCPPMexFile局限性

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

  • Options.language =“c++”

  • 对象使用下列Simulink对象之一IsAlias属性设置为真正的

    • 仿真软件。公共汽车

    • 仿真软件。AliasType

    • 仿真软件。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 - function的支持

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

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

  • 注册文件

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

  • TLC块文件

  • sFunction_makecfg.mrtwmakecfg.m文件

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

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

  • 在使用Simulink模型中部署的文件之前,将包含s函数文件的文件夹添加到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) = new addder #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 addder::add_one(int increment) {int_state += increment;返回int_state;}
  • 更新rtwdemo_sfun_adder_cpp.cpp更改如下:

    • StartFcnSpec调用分配新对象的宏加法器对象,并缓存指针。

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

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

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

另请参阅

相关的话题

Baidu
map