创建与simulink无缝合作的s函数金宝app®和代码生成器产品通过使用包装器概念。下载188bet金宝搏你可以:
通过编写MEX S函数包装器,在Simulink模型中连接金宝app算法(
).sfunction
.mex.
通过创建TLC S函数包装器,将代码生成器插入生成的代码(
).sfunction
.tlc
通过使用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 ++代码。前三个陈述:
定义S函数的名称(在Simulink S函数块对话框中输入的内容)。金宝app
指定S函数正在使用级别2格式。
提供访问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文件,它指定代码生成器如何调用您的代码。例如,您可以内联调用my_alg
在mdlOutputs
部分生成的代码。在墨西哥人s函数包装器例如,调用tomy_alg
是嵌入在mdlOutputs
部分为:
* y = my_alg(* Uptrs [0]);
当您创建TLC s函数包装器时,目标是在生成的代码中嵌入相同类型的调用。
查看代码生成器的执行方式是如何执行的函数。通过缺少文件来识别非束缚的S函数
以及sfunction
.tlc
.生成非束缚S函数的代码时,代码生成器会产生呼叫sfunction
.mex.mdlOutputs
通过函数指针,在此示例中,然后调用my_alg
.
包装器示例包含一个s函数,wrapsfcn.mex
.你必须编译和链接一个额外的模块,my_alg
,使用生成的代码。在MATLAB命令提示符处,输入:
设置参数(“包装/ s函数”,'sfunctionmodules','my_alg')
使用时生成的代码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函数,wrapsfcn.c
在里面mdlOutputs
通过使用此代码:
SimStruct *rts = ssgetfunction (rts, 0);sfcnOutputs (rts, tid);
这个调用有与之相关的计算开销。Simu金宝applink引擎创建一个SimStruct
S-Function块的数据结构。代码生成器通过函数指针构造一个要执行的调用mdlOutputs
,然后mdlOutputs
调用my_alg
.通过将呼叫联系到C / C ++算法,my_alg
,你可以消除两者SimStruct
和额外的函数呼叫,从而提高了所生成的代码的效率并减少尺寸。
内含包装器S函数需要一个
S函数的文件。TLC文件必须包含对的函数调用sfunction
.tlcmy_alg
. 这个figure shows the relationships between the algorithm, the wrapper S-function, and the
文件sfunction
.tlc
将调用内联到my_alg
,将函数调用放在
与s函数同名的文件(在本例中,sfunction
.tlcwrasefcn.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的内存使用。