主要内容

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

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

  • 通过编写MEX S函数包装器,在Simulink模型中连接金宝app算法(sfunction.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引擎喊道亚硝胺,即使这个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 *//**mdlInitializeSizes-初始化大小数组*/static void mdlInitializeSizes(SimStruct*S){sssetNumSfcnParms(S,0)/*输入参数的数量*/if(!ssSetNumInputPorts(S,1))返回;ssSetInputPortWidth(S,0,1);ssSetInputPortDirectFeedThrough(S,0,1);如果(!ssSetNumOutputPorts(S,1))返回;ssSetOutputPortWidth(S,0,1);ssSetNumSampleTimes(S,1);}/**MDLinitalizeSampleTimes-指示此S函数*以源(驱动块)*/static void MDLinitalizeSampleTimes(SimStruct*S){ssSetSampleTime(S,0,继承的采样时间)的速率运行;ssSetOffsetTime(S,0,0.0);}/**mdlOutputs-通过调用my_alg*计算输出,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中呼叫我的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函数的模板

功能的例程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);}

有关更多信息,请参阅管理构建过程文件依赖项

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

墨西哥wrapsfcn.cmy_alg.c.

TLC S函数包装器

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

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

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

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

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

设置参数(“包装/ 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) */ {/*非线性S函数创建SimStruct对象并*生成对S函数例程mdlOutputs的调用*/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用于包装器S-Function块。有一个孩子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. 这个figure shows the relationships between the algorithm, the wrapper S-function, and thesfunction.tlc文件

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

此代码是TLC文件wrasefcn.tlc.那环wrapsfcn.c

%%文件:wrapsfcn.tlc %%摘要:%%实施例内联对S-功能wrapsfcn.c TLC文件%%%实施 “wrapsfcn” “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函数时生成的代码与默认生成的代码类似。这个亚硝胺函数不包含对空函数的调用mdlOutputs函数现在直接调用my_alg

void mdlOutputs(int_T tid){/*Sin块:/Sin*/rtB.Sin=rtP.Sin.振幅*Sin(rtP.Sin.Frequency*ssGetT(rtS)+rtP.Sin.Phase);/*S-函数块:/S-函数*/rtB.S_函数=my_alg(rtB.Sin);/*内联调用my_alg *// *出口块: / out * / rty.out = RTB.S_FUNction;}

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

相关话题