文档

编写包装器S函数和TLC文件

创建与simulink无缝合作的s函数金宝app®和代码生成器产品通过使用包装器概念。下载188bet金宝搏你可以:

  • 通过编写MEX s -函数包装器(金宝appsfunction.mex.).

  • 通过创建TLC S函数包装器,将代码生成器插入生成的代码(sfunction.tlc).

墨西哥人s函数包装器

通过使用s函数包装器创建s函数,您可以在Simulink模型和生成的代码中插入C/ c++代码算法,而无需对原来的C/ c++函数进行少量或不进行任何更改。金宝appMEX s -函数包装器是调用驻留在另一个模块中的代码的s -函数。

请注意

仅在MATLAB中使用MEX S函数包装器®在其中创建包装器的版本。

假设您有一个算法(即C函数)调用my_alg驻留在文件中my_alg.c..你可以集成my_alg通过创建MEX金宝app S函数包装器来进入Simulink模型(例如,wrapsfcn.c).然后金宝app可以调用Simulink模型my_alg来自S函数块。Simu金宝applink S函数包含一组空心功能,即Simulink引擎需要各种API相关的目的。例如,虽然只有mdlOutputs调用my_alg引擎喊道mdlTerminate,即使这个s函数例程没有执行任何动作。

你可以嵌入呼叫my_alg在生成的代码中创建一个TLC s函数包装器(例如,wrasefcn.tlc.).您可以消除空函数调用。您可以避免执行mdlOutputs函数,然后可以消去my_alg函数。

当您创建过程性算法或将遗留代码集成到Simulink模型中时,包装器s -函数非常有用。金宝app如果你想创建以下代码:

  • 具有解释性(即通过操作模式高度参数化)

  • 大量优化(即,没有额外的测试来决定代码在运行的模式)

那么您必须为S-function创建一个完全内联的TLC文件。

下图显示了包装器S函数概念。

使用s函数包装器将算法导入到你的Simulink模型中,这意味着s函数作为一个接口来调用你的C/ c++算法金宝appmdlOutputs.您可以快速将大型独立C / C ++程序集成到模型中,而无需更改代码。

此示例模型包括S函数包装器。

两个文件与之相关联Wrapsfcn.块:S函数包装器和包含算法的C / C ++代码。前三个陈述:

  1. 定义S函数的名称(在Simulink S函数块对话框中输入的内容)。金宝app

  2. 指定s -函数使用级别2格式。

  3. 提供访问SimStruct数据结构。SimStruct属性中包含指向模拟和代码生成期间使用的数据的指针,并定义在其中存储数据和从SimStruct

#define S_FUNCTION_NAME wrapsfcn #define S_FUNCTION_LEVEL 2 #include " simstruct .h" extern real_T my_alg(real_T u);/*将my_alg声明为extern *//* * mdlinitializesize -初始化大小数组*/ static void mdlinitializesize (SimStruct *S) {ssSetNumSFcnParams(S, 0);/*输入参数的个数*/ if (!ssSetNumInputPorts(年代,1))返回;ssSetInputPortWidth (0, 1);ssSetInputPortDirectFeedThrough (0, 1);如果(! ssSetNumOutputPorts(年代,1))返回;ssSetOutputPortWidth (0, 1);ssSetNumSampleTimes (S, 1);/* * mdlInitializeSampleTimes -表示该S函数以源(驱动块)的速率运行*/ static void mdlInitializeSampleTimes(SimStruct *S) {ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);ssSetOffsetTime(年代,0,0.0);} /* * mdlOutputs -通过调用驻留在另一个模块中的my_alg来计算输出,my_alg.c */ static void mdlOutputs(SimStruct *S, int_T tid) {InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); *y = my_alg(*uPtrs[0]);/*在mdlOutputs中调用my_alg */} /* * mdlTerminate -在模拟终止时调用。*/ /静态void mdlTerminate(SimStruct *S) {} #ifdef MATLAB_MEX_FILE /*这个文件被编译为一个mex文件吗?*/ #include "金宝appsimulink.c" /* MEX-file接口机制*/ #else #include "cg_sfun.h" /*代码生成注册函数*/ #endif .h

有关更多信息,请参阅C s -函数模板(金宝appSimulink)。

功能的例程mdlOutputs包含函数调用my_alg,它是包含s函数执行的算法的C函数。为my_alg.c.,代码为:

#ifdef MATLAB_MEX_FILE #include "tmwtypes.h" #else #include "rtwtypes.h" #endif real_T my_alg(real_T u) {return(u * 2.0);}

有关更多信息,请参阅管理构建过程文件依赖项(金宝app仿真软件编码器)。

包装器函数Wrapsfcn.调用my_alg,计算U * 2.0.构建wrapsfcn.mex,使用下面的命令:

墨西哥人wrapsfcn.cmy_alg.c.

TLC s函数包装器

TLC s -函数包装器是一个TLC文件,它指定代码生成器如何调用您的代码。例如,您可以内联调用my_algmdlOutputs部分生成的代码。在墨西哥人s函数包装器(金宝appSimulink Coder)的例子,调用my_alg是嵌入在mdlOutputs部分为:

* y = my_alg(* Uptrs [0]);

当您创建TLC s函数包装器时,目标是在生成的代码中嵌入相同类型的调用。

查看代码生成器的执行方式是如何执行的函数。通过缺少文件来识别非束缚的S函数sfunction.tlc和存在sfunction.mex..生成非束缚S函数的代码时,代码生成器会产生呼叫mdlOutputs通过函数指针,在此示例中,然后调用my_alg

包装器示例包含一个s函数,wrapsfcn.mex.你必须编译和链接一个额外的模块,my_alg,使用生成的代码。在MATLAB命令提示符处,输入:

set_param (“包装/ s函数”'sfunctionmodules'“my_alg”

非内联s函数的代码开销

使用时生成的代码grt.tlc作为系统目标文件没有wrasefcn.tlc.是:

为包装器模型生成代码注释非纳诺wrapsfcn S-function> #include  #include  #include "wrapper.h" #include "wrapper.h"人口、难民和移民事务局“/ *启动模式* /空白mdlStart (void){/ *(启动代码不是必需的 ) */ } /* 计算块输出* /空白mdlOutputs (int_T tid){/ *罪:< Root > / * / rtB的罪。rtP.Sin.振幅* Sin (rtP.Sin. Sin。频率* ssGetT(rtS) + rtP.Sin.Phase);/* Level2 S-Function块:/S-Function (wrapsfcn) */ {/* noninline S-functions创建一个SimStruct对象,并生成一个对S-function例程的调用SimStruct *rts = ssgetfunction (rts, 0);sfcnOutputs (rts, tid);} / *出口块: / out * / rty.out = rtb.s_function;} / *执行型号更新* / void mdlupdate(int_t tid){/ *(不需要更新代码)* /} / *终止功能* / void mdlterminate(void){/ * level2 s函数块: /S函数(Wrapsfcn)* / {/* noninline S-functions需要一个SimStruct对象和*调用S-function例程mdlTerminate */SimStruct *rts = ssgetfunction (rts, 0);sfcnterminate(RTS);#include“wrapper.reg”/ * [eof] wrapper.c * /

wrapper.reg生成的文件包含SimStruct对于包装函数块。有一个孩子SimStruct用于模型中的每个S-Function块。通过为S-function创建TLC包装器,可以显著减少这种开销。

内联包装器s -函数

生成的代码会调用您的s函数,wrapsfcn.c,在mdlOutputs通过使用以下代码:

SimStruct *rts = ssgetfunction (rts, 0);sfcnOutputs (rts, tid);

这个调用有与之相关的计算开销。Simu金宝applink引擎创建一个SimStructS-Function块的数据结构。代码生成器通过函数指针构造一个要执行的调用mdlOutputs,然后mdlOutputs调用my_alg.通过将呼叫联系到C / C ++算法,my_alg,你可以消除两者SimStruct和额外的函数呼叫,从而提高了所生成的代码的效率并减少尺寸。

内含包装器S函数需要一个sfunction.tlcs函数的文件。TLC文件必须包含调用的函数my_alg.图中显示了算法、包装器s函数和sfunction.tlc文件。

来内联调用my_alg,将函数调用放在sfunction.tlc与s函数同名的文件(在本例中,wrasefcn.tlc.).目标语言编译器覆盖了在生成的代码中调用s函数的默认方法。

这段代码就是TLC文件wrasefcn.tlc.那环wrapsfcn.c

%%文件:wrapsfcn.tlc %%摘要:%%示例的S函数的Inlined TLC文件wcn.c %%%实现“wrasefcn”“c”%%函数:blocktypesetup ==================================================== %%摘要:%%创建函数原型在model.h中:%%“extern real_t my_alg(real_t u);”%%%函数blocktypesetup(块,系统)void%Openfile缓冲区Extern real_t my_alg(real_t u);/*这一行放在wrapper.h */中%关闭文件缓冲%%Endfunction %% BlockTypesetup %%功能:输出=========================================================== %%摘要:%% y = my_alg(u);%%函数输出(块,系统)输出/ *%块:% * /%分配u = libblockinputsignal(0,“,”,“,0)%指定y = libblockoutputsignal(0,”“,”,0)%%提供“算法”的调用语句%%下面的行被展开并放在wrapper.c中的mdlOutputs中% < y > = my_alg (% u > <);% endfunction % %输出

该代码的第一部分内联Wrapsfcn.s -函数块,并在C语言中生成代码:

%实现“wrapsfcn”“C”

下一个任务是通知代码生成器的例程my_alg必须声明为外部生成的包皮申请文件Wrapsfcn.模型中的s功能块。这个宣言是一次性的吗Wrapsfcn.使用函数块使用BlockTypeSetup函数。在此功能中,您将指导目标语言编译器创建缓冲区并缓存my_alg作为走读生包皮生成的头文件。

最后一步是内联对函数的调用my_alg.的输出函数inlining呼叫。在此功能中,您可以访问块输入和输出并直接呼叫my_alg.调用被嵌入包装布

内联的代码

内联包装器S-function时生成的代码与默认生成的代码类似。的mdlTerminate函数不包含对空函数的调用mdlOutputs函数现在直接调用my_alg

void mdlOutputs(int_T tid) {/* Sin Block: /Sin */ rtB. txt;rtP.Sin.振幅* Sin (rtP.Sin. Sin。频率* ssGetT(rtS) + rtP.Sin.Phase);/* S-Function Block: /S-Function */ rtB. txt;S_Function = my_alg (rtB.Sin);/*内联调用my_alg *// *出口块: / out * / rty.out = RTB.S_FUNction;}

wrapper.reg不创造一个孩子SimStruct,因为生成的代码正在调用my_alg直接消除超过1 KB的内存使用。

相关的话题