文档

编写包装器S-Function和TLC文件

创建与Simulink无缝配合的s函数金宝app®以及使用包装器概念的代码生成器产品。下载188bet金宝搏您可以:

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

  • 通过创建TLC S-function包装器(sfunction.tlc).

MEX 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 -函数包装器(例如,wrapsfcn.c).然后金宝app,Simulink模型可以调用my_alg从S-Function块。Simu金宝applink s函数包含一组空函数,用于Simulink引擎与各种API相关的目的。例如,虽然只有mdlOutputs调用my_alg,引擎呼叫mdlTerminate,即使这个s函数例程不执行任何操作。

可以将调用嵌入到my_alg通过创建TLC S-function包装器(例如,wrapsfcn.tlc).可以消除空函数调用。可以避免执行的开销mdlOutputs函数,然后就可以消去my_alg函数。

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

  • 本质上的解释性(也就是说,操作模式高度参数化)

  • 高度优化(也就是说,没有额外的测试来决定代码在什么模式下运行)

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

下一个图显示了包装器s -函数的概念。

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

这个示例模型包括一个s函数包装器。

控件关联了两个文件wrapsfcn块:s函数包装器和包含算法的C/ c++代码。前三个陈述:

  1. 定义s函数的名称(您在Simulink S-function块对话框中输入的名称)。金宝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(S, 1))返回;sssetinputporttwidth (S, 0,1);ssSetInputPortDirectFeedThrough(S, 0,1);if (!ssSetNumOutputPorts(S,1));ssSetOutputPortWidth(S, 0,1);ssSetNumSampleTimes(S, 1);} /* * mdlInitializeSampleTimes -表示该S函数以源(驱动块)的速率* */静态无效mdlInitializeSampleTimes(SimStruct *S) {ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);ssSetOffsetTime(S, 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 -在模拟终止时调用。*/ static void mdlTerminate(SimStruct *S) {} #ifdef MATLAB_MEX_FILE /*这个文件被编译为墨西哥文件吗?*/ #include "金宝appsimulink.c" /* *墨西哥文件接口机制*/ #else #include "cg_sfun.h" /*代码生成注册函数*/ #endif .c

有关更多信息,请参见C - s - function的模板(金宝app模型)。

s函数例程mdlOutputs的函数调用my_alg,它是C函数,包含s函数执行的算法。为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-function包装器是一个TLC文件,它指定代码生成器如何调用您的代码。例如,可以将调用内联到my_algmdlOutputs部分生成的代码。在MEX s -函数包装器例如,调用my_alg是嵌入在mdlOutputs部分为:

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

在创建TLC S-function包装器时,目标是在生成的代码中嵌入相同类型的调用。

看看代码生成器是如何执行未内联的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作为系统目标文件没有wrapsfcn.tlc是:

为包装器模型生成代码注释noninlinedwrapsfcn S-function> #include  #include  #include "wrapper.h" #include "wrapper.h"/*启动模型*/ void mdlStart(void){/*(不需要启动代码)*/}/*计算块输出*/ void mdlOutputs(int_T tid) {/* Sin block: /Sin */ rtB. prm" /*启动模型*/ void mdlStart(void){/*计算块输出*/ void mdlOutputs(int_T tid) {/* Sin block: /Sin */ rtB. prm"Sin = rtP.Sin.振幅* Sin (rtP.Sin)。频率* ssGetT(rtS) + rtP.Sin.Phase);/* Level2 S-Function块:/S-Function (wrapsfcn) */ {/*非内联s函数创建一个SimStruct对象,并生成对s函数例程mdlOutputs的调用SimStruct *rts = ssgetfunction (rts, 0);sfcnOutputs (rts, tid);} /* Outport Block: /Out */ rtY. txtOut = rtB.S_Function;} /*执行模型更新*/ void mdlUpdate(int_T tid){/*(不需要更新代码)*/}/*终止函数*/ void mdlTerminate(void) {/* Level2 S-Function Block: /S-Function (wrapsfcn) */ {/*非内联s函数需要一个SimStruct对象和调用s函数例程mdlTerminate */SimStruct *rts = ssgetfunction (rts, 0);sfcnTerminate (rts);}} #包含“包装器”。reg" /* [EOF] wrapper.c */

wrapper.reg的初始化SimStruct用于包装器S-Function块。只有一个孩子SimStruct为模型中的每个S-Function块。通过为s函数创建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.tlc文件的s函数。TLC文件必须包含对的函数调用my_alg.该图显示了算法、包装器s函数和sfunction.tlc文件。

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

这段代码就是TLC文件wrapsfcn.tlc,内联wrapsfcn.c

%%文件:wrapsfcn。tlc % %文摘:% % s函数内联tlc文件例子wrapsfcn.c % % %实现“wrapsfcn”“C”% %功能:BlockTypeSetup  ==================================================== %% 文摘:% %在model.h创建函数原型为:% %”走读生real_T my_alg (real_T u);“%% %函数BlockTypeSetup(block, system) void %openfile buffer extern real_T my_alg(real_T u);/*这一行放在wrapper.h */中% closefile缓冲% < LibCacheFunctionPrototype(缓冲)> % endfunction % % BlockTypeSetup % %功能:输出  =========================================================== %% 文摘:% % y = my_alg (u);%% %function Output (block, system) Output /* % block: % */ %assign u = LibBlockInputSignal(0, "", ", 0) %assign y = LibBlockOutputSignal(0, "", ", 0) %%为"algorithm"提供调用语句下面的行展开并放在wrapper.c中的mdlOutputs中% = my_alg(%);输出

代码的第一部分内联了wrapsfcnS-Function块,在C中生成代码:

%实现"wrapsfcn" "C"

下一个任务是通知代码生成器例程my_alg必须声明为外部在生成wrapper.h申请任何wrapsfcn模型中的s -功能块。这个声明是一劳永逸的吗wrapsfcn函数块BlockTypeSetup函数。在此函数中,指示目标语言编译器创建缓冲区并缓存my_alg作为走读生wrapper.h生成的头文件。

最后一步是内联对函数的调用my_alg.的输出函数内联调用。在这个函数中,您访问块输入和输出,并对其进行直接调用my_alg.电话是嵌入在wrapper.c

内联代码

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

void mdlOutputs(int_T tid) {/* Sin Block: /Sin */ rtB。Sin = rtP.Sin.振幅* Sin (rtP.Sin)。频率* ssGetT(rtS) + rtP.Sin.Phase);/* S-Function块:/S-Function */ rtB。S_Function = my_alg(rtB.Sin);/* my_alg */的内联调用/* Outport Block: /Out */ rtY。Out = rtB.S_Function;}

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

相关的话题