主要内容

已有函数中的持久性内存

此示例说明如何使用代码继承工具将已有 C 函数与特定于实例的持久性内存相集成。

代码继承工具允许您:

  • 提供已有函数设定;

  • 生成 C-MEX S-Function,在仿真期间使用它来调用现有代码;以及

  • 编译和构造生成的 S-Function 以进行仿真。

提供已有函数设定

代码继承工具附带的函数接受特定的数据结构体或结构体数组作为参量。可以通过调用函数 legacy_code() 并使用 'initialize' 作为第一个输入来初始化数据结构体。初始化结构体之后,您必须将其属性指定给与要集成的现有代码对应的值。此示例中调用的已有函数的原型为:

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 是用于应用单积分步长延迟的特定于实例的持久性内存。COUNTERBUS 是在 counterbus.h 中定义的结构体 typedef,并在基础工作区中使用 Simulink.Bus 对象实现。已有源代码位于文件 memory_bus.hmemory_bus.c 中。

evalin('base','load sldemo_lct_data.mat')

% sldemo_sfun_work
def = legacy_code('initialize');
def.SFunctionName = 'sldemo_sfun_work';
def.InitializeConditionsFcnSpec = 'void memory_bus_init(COUNTERBUS work1[1], int32 p1, int32 p2)';
def.OutputFcnSpec = 'void memory_bus_step(COUNTERBUS u1[1], COUNTERBUS work1[1], COUNTERBUS y1[1])';
def.HeaderFiles   = {'memory_bus.h'};
def.SourceFiles   = {'memory_bus.c'};
def.IncPaths      = {'sldemo_lct_src'};
def.SrcPaths      = {'sldemo_lct_src'};

生成和编译 S-Function 以供仿真期间使用

再次调用函数 legacy_code() 并将第一个输入设置为 'generate_for_sim',以便根据输入参量 'def' 提供的描述自动生成和编译 C-MEX S-Function。此 S-Function 用于在仿真中调用已有函数。S-Function 的源代码位于文件 sldemo_sfun_work.c 中。

legacy_code('generate_for_sim', def);
### Start Compiling sldemo_sfun_work
    mex('-I/tmp/Bdoc25b_2988451_772498/tp4d7de9fa/simulink_features-ex40483229/sldemo_lct_src', '-I/tmp/Bdoc25b_2988451_772498/tp4d7de9fa/simulink_features-ex40483229', '-c', '-outdir', '/tmp/Bdoc25b_2988451_772498/tp2d7422a7_e352_4328_89a0_e227a10b302b', '/tmp/Bdoc25b_2988451_772498/tp4d7de9fa/simulink_features-ex40483229/sldemo_lct_src/memory_bus.c')
Building with 'gcc'.
MEX completed successfully.
    mex('sldemo_sfun_work.c', '-I/tmp/Bdoc25b_2988451_772498/tp4d7de9fa/simulink_features-ex40483229/sldemo_lct_src', '-I/tmp/Bdoc25b_2988451_772498/tp4d7de9fa/simulink_features-ex40483229', '/tmp/Bdoc25b_2988451_772498/tp2d7422a7_e352_4328_89a0_e227a10b302b/memory_bus.o')
Building with 'gcc'.
MEX completed successfully.
### Finish Compiling sldemo_sfun_work
### Exit

生成 rtwmakecfg.m 文件以进行代码生成

在创建 TLC 模块文件后,可再次调用函数 legacy_code() 并将第一个输入设置为 'rtwmakecfg_generate',以生成 rtwmakecfg.m 文件来通过 Simulink® Coder™ 支持代码生成。如果 S-Function 需要的源文件和头文件与 S-Function 不在同一个文件夹中,而您要将这些依赖项添加到代码生成过程中生成的联编文件中,请生成 rtwmakecfg.m 文件。

注意:仅当要在加速模式下仿真模型时,才完成此步骤。

legacy_code('rtwmakecfg_generate', def);

生成封装的 S-Function 模块以调用生成的 S-Function

在编译 C-MEX S-Function 源代码后,可以再次调用函数 legacy_code() 并将第一个输入设置为 'slblock_generate',以生成配置为调用该 S-Function 的封装 S-Function 模块。此模块放置在新模型中,并且可以复制到现有模型中。

% legacy_code('slblock_generate', def);

集成现有代码

模型 sldemo_lct_work 显示与现有代码的集成。子系统 memory_bus 的作用相当于调用已有 C 函数的工具。

open_system('sldemo_lct_work')
open_system('sldemo_lct_work/memory_bus')
sim('sldemo_lct_work')
ans = 

  Simulink.SimulationOutput:
             ScopeDataA: [11x3 double] 
                   tout: [11x1 double] 

     SimulationMetadata: [1x1 Simulink.SimulationMetadata] 
           ErrorMessage: [0x0 char] 

另请参阅