用mdlRTW例程编写完全内联的s -函数

通过使用s函数,您可以内联更复杂的s函数mdlRTW例行公事。的mdlRTW例程通过创建用于TLC文件的非可调参数的参数记录,向代码生成过程提供关于如何内联s -函数的更多信息。的mdlRTW例程把信息放在模型.rtw文件。的mdlRTW函数在文本文件中描述matlabroot/万博1manbetx模型/ src /sfuntmpl_doc.c

使用mdlRTW函数,请执行步骤创建直接索引查找s函数。查找表是函数的有序数据点的集合。通常,这些表使用一些插值方案来近似已知数据点之间的相关函数值。将查找表算法示例合并到Simulink中万博1manbetx®模型中,第一步是编写一个s函数来执行算法mdlOutputs.为了生成最有效的代码,下一步是创建相应的TLC文件,以消除计算开销并提高查找计算的速度。

Simu万博1manbetxlink产品支持两种通用的1-D和2-D查找算法。万博1manbetx您可以直接使用这些算法,或者创建一个自定义查找表s -函数来满足您的需求。你可以创建一个一维查找s函数,sfun_directlook.c,及其相应的内联sfun_directlook.tlc文件(见目标语言编译器更多的细节)。您可以:

  • s函数参数的错误检查。

  • 缓存在模型执行期间不更改的s函数的信息。

  • 使用mdlRTW函数自定义代码生成器,以便为给定的一组块参数生成最优代码。

  • 创建一个薄层色谱文件,该文件可以完全内联查找表代码,也可以调用查找表算法的包装器函数。

s函数RTWdata

RTWdata是块的一个属性,目标语言编译器在内联s函数时可以使用它。RTWdata是可以附加到块上的字符向量结构。RTWdata与模型一起保存,并放置在模型.rtw文件在生成代码时。例如,这一套MATLAB®命令:

mydata。field1 =“field1信息”;mydata。field2 =“field2信息”;set_param (gcb),“RTWdata”, mydata) get_param (gcb,“RTWdata”

产生这一结果:

ans = field1:“field1信息”field2:“field2信息”

中关联的S-Function块的信息模型.rtw文件是:

Block {Type "S-Function" RTWdata {field1" info for field1" field2" information for field2"}

请注意

RTWdata保存在模型文件中,用于未链接到库的s -函数。然而,RTWdata不持久用于链接到库的S-Function块。

直接索引查找表算法

Simulink库中提供的一维查找表块在计算输出时使用插值或外推法。万博1manbetx在本例中,您创建了一个查找表,它直接对输出向量(y-数据向量),基于当前输入(x拼点。

这个直接的一维查找示例计算一个近似解p (x)到一个部分已知的函数f (x)x = x0,给定的数据点对(x, y)以…的形式x-数据向量和ay拼向量。对于给定的数据对(例如i两人),y_i = f (x_i).假设x-数据值单调递增。如果x0是在?的范围之外x-data向量,返回第一个或最后一个点。

s函数的参数为:

XData、YData XEvenlySpaced

XDataYData是表示未知函数值的等长双向量。XDataEvenlySpaced是一个标量,0.0假和1.0为真实的。如果XData向量是等间距的,XDataEvenlySpaced1.0生成更高效的代码。

该图显示了参数如何XData = [1:6]YData =[1、2、7、4、5、9)处理。例如,如果输入(x-value)的S-Function块值为3,则输出(y值)7。

直接索引查询表示例

通过将直接索引s函数与TLC文件内联来改进查找表。这个直接索引查找表s -函数不需要TLC文件。该示例为直接索引查找表s -函数使用了一个TLC文件,以减少代码大小并提高生成代码的效率。

使用内联TLC文件实现直接索引算法需要S-function主模块,sfun_directlook.c和一个相应的lookup_index.c模块。的lookup_index.c模块包含GetDirectLookupIndex函数,该函数用于定位XData对当前x输入值时XData间隔是不均匀的。的GetDirectLookupIndex例程从s函数和生成的代码中调用。该示例使用包装器概念在Simulink mex文件和生成的代码之间共享C/ c++代码。万博1manbetx

如果XData,则s -函数主模块和生成的代码都包含查找算法来计算y-给定值x-value因为算法很短。

内联的TLC文件为sfun_directlook.tlc,用于执行包装器调用或嵌入s函数的最佳C/ c++代码。(参见mdlRTW用法).

错误处理

sfun_directlook.tlc,mdlCheckParameters常规检查:

  • 新参数设置有效。

  • XDataYData都是相同长度的包含有限实数的向量。

  • XDataEvenlySpaced是一个标量。

  • XData向量是单调递增的等间距向量。

mdlInitializeSizes函数显式地调用mdlCheckParameters在它验证传递给s函数的参数数量之后。在Simulink引万博1manbetx擎调用之后mdlInitializeSizes,然后调用mdlCheckParameters当您更改参数或重新计算它们时。

用户数据缓存

sfun_directlook.tlc,mdlStart例程显示了如何缓存在模拟过程中或在生成的代码执行时不会更改的信息。的值被缓存XDataEvenlySpaced参数用户数据,一个领域的SimStruct.下面一行mdlInitializeSizes指示Simulink引擎禁止万博1manbetx更改XDataEvenlySpaced

ssSetSFcnParamTunable (S iParam SS_PRM_NOT_TUNABLE);

在执行期间,mdlOutputs访问的值XDataEvenlySpaced用户数据而不是叫mxGetPrMATLAB API函数。

mdlRTW用法

代码生成器调用mdlRTW例程,同时生成模型.rtw文件。要为您的Simulink模型生成最佳代码,您可以将信息添加到万博1manbetx模型.rtw关于S-Function块运行的模式的文件。

的参数设置模型.rtw文件。参数设置在执行过程中不会改变。在这种情况下XDataEvenlySpaceds函数参数在执行过程中不能改变(ssSetSFcnParamTunable被指定为假(0在…内mdlInitializeSizes).参数设置(XSpacing)使用函数ssWriteRTWParamSettings

因为xDatayData中是否注册为运行时参数mdlSetWorkWidths,代码生成器写入模型.rtw自动文件。

在检查s函数和内联TLC文件之前,考虑为这个模型生成的代码。

模型使用均匀间隔XData在顶部的s -函数块和不均匀间隔XData在s功能块的底部。在创建此模型时,为每个S-Function块指定以下命令。

set_param (“sfun_directlook_ex / s函数”“SFunctionModules”“lookup_index”) set_param (“sfun_directlook_ex / S-Function1”“SFunctionModules”“lookup_index”

构建流程使用该模块lookup_index.c当创建可执行文件时。

在为这个模型生成代码时,代码生成器使用s函数mdlRTW方法生成模型.rtw文件的值EvenlySpacedXSpacing参数为顶部s -功能块和值UnEvenlySpacedXSpacing参数用于底部s -函数块。tlc文件使用的值XSpacing以确定在生成的代码中包含什么算法。生成的代码包含查找算法XData是等间距的,但叫GetDirectLookupIndex常规的时XData间隔是不均匀的。生成的模型.c模型. cpp查找表示例模型的代码类似于下面的代码:

/* * sfun_directlook_ex.c * * Simulink模型的代码生成* "sf万博1manbetxun_directlook_ex.slx"。*……*/ #include "sfun_directlook_ex.h" #include "sfun_directlook_ex_private.h" /*外部输出(由自动存储信号提供的根输出)*/ ExtY_sfun_directlook_ex_T sfun_directlook_ex_Y;/*实时模型*/ RT_MODEL_sfun_directlook_ex_T sfun_directlook_ex_M_;RT_MODEL_sfun_directlook_ex_T *const sfun_directlook_ex_M = &sfun_directlook_ex_M_;/*模型输出函数*/ void sfun_directlook_ex_output(void){/*局部块i/o变量*/ real_T rtb_SFunction;real_T rtb_SFunction1;/* Sin: '/Sine Wave' */ rtb_SFunction1 = Sin (sfun_directlook_ex_M->Timing.t[0]);/* sfun_directlook_ex模型中顶部S-function块的内联代码*//* S-Function (sfun_directlook): '/S-Function' */ {const real_T *xData = sfun_directlook_ex_const_sfunction_xdata;const real_T *yData = sfun_directlook_ex_const_sfunction_ydata;real_T spacing = xData[1] - xData[0];if (rtb_SFunction1 <= xData[0]) {rtb_SFunction1 = yData[0];} else if (rtb_SFunction1 >= yData[20]) {rtb_SFunction = yData[20];} else {int_T idx = (int_T)((rtb_SFunction1 - xData[0]) / spacing);rtb_SFunction = yData [idx];}} /* Outport: '/Out1' */ sfun_directlook_ex_Y. txt . txt着干活= rtb_SFunction;/* sfun_directlook_ex模型中底部S-function块的内联代码*//* S-Function (sfun_directlook): '/S-Function1' */ {const real_T *xData = sfun_directlook_ex_const_sfunction1_xdata;const real_T *yData = sfun_directlook_ex_const_sfunction1_ydata;int_T idx;idx = GetDirectLookupIndex(xData, 5, rtb_SFunction1);rtb_SFunction1 = yData [idx];} /* Outport: '/Out2' */ sfun_directlook_ex_Y. txt . txtOut2 = rtb_SFunction1;} / *模型更新函数* /空白sfun_directlook_ex_update (void){/ *信号主要停止模拟* /{/ *样品时间:[0.0,0.0 s] * /如果((rtmGetTFinal (sfun_directlook_ex_M) ! = 1) & & ! ((rtmGetTFinal (sfun_directlook_ex_M) -sfun_directlook_ex_M - > Timing.t [0]) > sfun_directlook_ex_M - >时机。t[0] * (DBL_EPSILON)) {rtmSetErrorStatus(sfun_directlook_ex_M, "仿真完成");}} /*更新基本速率的绝对时间*/ /*“clockTick0”计算这个任务的代码被执行的次数。绝对时间是“clockTick0”*和“Timing.stepSize0”的乘积。“clockTick0”的大小确保计时器在选定的应用程序生命周期内不会*溢出。 * Timer of this task consists of two 32 bit unsigned integers. * The two integers represent the low bits Timing.clockTick0 and the high bits * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment. */ if (!(++sfun_directlook_ex_M->Timing.clockTick0)) { ++sfun_directlook_ex_M->Timing.clockTickH0; } sfun_directlook_ex_M->Timing.t[0] = sfun_directlook_ex_M->Timing.clockTick0 * sfun_directlook_ex_M->Timing.stepSize0 + sfun_directlook_ex_M->Timing.clockTickH0 * sfun_directlook_ex_M->Timing.stepSize0 * 4294967296.0; } ...

相关的话题