主要内容

探索变量名和循环滚动

timesN循环教程概述

摘要目的:这个例子展示了如何影响生成代码的循环行为。

文件夹:matlabroot/工具箱/ rtw / rtwdemos / tlctutorial / timesN开放

使用模型sfun_xNtlctutorial / timesN.它有一个来源(a正弦波发电机块),a* N增益块,Block和范围块。

本教程指导您完成以下步骤:

  1. 开始-建立练习并运行模型

  2. 修改模型-改变输入宽度并查看结果

  3. 修改循环滚动阈值—修改阈值,查看结果

  4. 更多关于TLC循环滚动-参数化循环行为

开始

  1. 使tlctutorial / timesN您的当前文件夹,以便使用提供的文件。

    请注意

    的外部使用或创建工作文件夹matlabroot对于仿真金宝app软件®你做的模型。您不能在源文件夹中构建模型。

  2. 在MATLAB中®命令窗口,为s函数创建一个mexo文件:

    墨西哥人timesN.c

    这避免了使用Simulink附带的版本。金宝app

    请注意

    如果您之前没有运行过,则可能会出现错误墨西哥人设置

  3. 打开模型文件sfun_xN

  4. 中查看先前生成的代码sfun_xN_grt_rtw / sfun_xN.c.注意,代码中不存在循环。这是因为输入和输出信号是标量。

修改模型

  1. 取代正弦波常数块。

  2. 的参数常数块为1:4,改变顶部标签,模型:sfun_xN,模型:sfun_vec

  3. 将编辑后的模型保存为sfun_vec(在tlctutorial / timesN)。模型现在看起来是这样的。

  4. 因为常数块生成一个矢量的值,这是一个矢量化模型。生成模型的代码并查看/*模型输出函数*/的部分sfun_vec.c在编辑器中观察变量如何和循环被处理。该函数如下所示:

    /*模型输出函数*/ static void sfun_vec_output(int_T tid) {/* S-Function Block: /S-Function */ /*输入乘以3.0 */ sfun_vec_B. / /* S-Function function: timesN_output[0] = sfun_vec_P。Constant_Value[0] * 3.0;sfun_vec_B。timesN_output[1] = sfun_vec_P.Constant_Value[1] * 3.0; sfun_vec_B.timesN_output[2] = sfun_vec_P.Constant_Value[2] * 3.0; sfun_vec_B.timesN_output[3] = sfun_vec_P.Constant_Value[3] * 3.0; /* Outport: '/Out' */ sfun_vec_Y.Out[0] = sfun_vec_B.timesN_output[0]; sfun_vec_Y.Out[1] = sfun_vec_B.timesN_output[1]; sfun_vec_Y.Out[2] = sfun_vec_B.timesN_output[2]; sfun_vec_Y.Out[3] = sfun_vec_B.timesN_output[3]; UNUSED_PARAMETER(tid); }

    注意,生成模型输出的代码有四个实例,对应于四个迭代。

  5. 的参数常数块到1:10,并保存模型。

  6. 生成模型的代码并查看/*模型输出函数*/的部分sfun_vec.c在编辑器中观察变量如何和循环被处理。该函数如下所示:

    /*模型输出函数*/ static void sfun_vec_output(int_T tid) {/* S-Function Block: /S-Function */ /*输入乘以3.0 */ {int_T i1;const real_T *u0 = &sfun_vec_P.Constant_Value[0];real_T *y0 = sfun_vec_B.timesN_output;(i1 = 0;I1 < 10;I1 ++) {y0[I1] = u0[I1] * 3.0;}} {int32_T i;For (i = 0;I < 10;i++) {/* Outport: '/Out' */ sfun_vec_Y. Outport: '/Out'Out[i] = sfun_vec_B.timesN_output[i]; } } UNUSED_PARAMETER(tid); }

注意:

  • 生成模型输出的代码被“滚动”到一个循环中。当迭代次数超过5时,默认会发生这种情况。

  • 循环索引i1取值范围为0 ~ 9。

  • 指针* y0使用并初始化为输出信号数组。

修改循环滚动阈值

类的当前值,代码生成器将创建迭代或循环环展开阈值参数。

的默认值环展开阈值5.更改模型中块的循环行为:

  1. 优化窗格的“配置参数”对话框中,设置环展开阈值12并点击应用

    的参数RollThreshold现在是12.只有当信号穿过一个块的宽度超过12时,才会产生循环。

    请注意

    你不能修改RollThreshold从“配置参数”对话框中获取特定块。

  2. 新闻Ctrl + B重新生成输出。

  3. 检查sfun_vec.c.它看起来是这样的:

    /*模型输出函数*/ static void sfun_vec_output(int_T tid) {/* S-Function Block: /S-Function */ /*输入乘以3.0 */ sfun_vec_B. / /* S-Function function: timesN_output[0] = sfun_vec_P。Constant_Value[0] * 3.0;sfun_vec_B。timesN_output[1] = sfun_vec_P.Constant_Value[1] * 3.0; sfun_vec_B.timesN_output[2] = sfun_vec_P.Constant_Value[2] * 3.0; sfun_vec_B.timesN_output[3] = sfun_vec_P.Constant_Value[3] * 3.0; sfun_vec_B.timesN_output[4] = sfun_vec_P.Constant_Value[4] * 3.0; sfun_vec_B.timesN_output[5] = sfun_vec_P.Constant_Value[5] * 3.0; sfun_vec_B.timesN_output[6] = sfun_vec_P.Constant_Value[6] * 3.0; sfun_vec_B.timesN_output[7] = sfun_vec_P.Constant_Value[7] * 3.0; sfun_vec_B.timesN_output[8] = sfun_vec_P.Constant_Value[8] * 3.0; sfun_vec_B.timesN_output[9] = sfun_vec_P.Constant_Value[9] * 3.0; /* Outport: '/Out' */ sfun_vec_Y.Out[0] = sfun_vec_B.timesN_output[0]; sfun_vec_Y.Out[1] = sfun_vec_B.timesN_output[1]; sfun_vec_Y.Out[2] = sfun_vec_B.timesN_output[2]; sfun_vec_Y.Out[3] = sfun_vec_B.timesN_output[3]; sfun_vec_Y.Out[4] = sfun_vec_B.timesN_output[4]; sfun_vec_Y.Out[5] = sfun_vec_B.timesN_output[5]; sfun_vec_Y.Out[6] = sfun_vec_B.timesN_output[6]; sfun_vec_Y.Out[7] = sfun_vec_B.timesN_output[7]; sfun_vec_Y.Out[8] = sfun_vec_B.timesN_output[8]; sfun_vec_Y.Out[9] = sfun_vec_B.timesN_output[9]; UNUSED_PARAMETER(tid); }
  4. 若要再次激活循环滚动,请更改环展开阈值到10个(或更少)上优化窗格。

循环滚动是优化生成代码的重要TLC功能。在为生产需求生成代码之前,花一些时间研究和探索它的含义。

更多关于TLC循环滚动

以下TLC%卷代码是输出的函数timesN.tlc

%function Outputs(block, system) Output /* % block: % */ %% /* Multiply input by % */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars % = \ % * %;%endroll %endfunction %%输出

理由%卷

之间的线条%卷和%endroll可能是重复的,也可能是循环的。理解的关键%卷Directive在其参数中是:

%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
论点 描述
sigIdx

将索引指定为生成代码中使用的(信号)向量。如果信号是标量,在分析该块时模型.rtw文件,TLC确定只需要一行代码。在这种情况下,它会凝固sigIdx0因此只访问向量的第一个元素,不构造循环。

液位控制阀

控件中指定的控制变量%卷指令是lcv = RollThresholdRollThreshold是一个默认值为5的全局(模型范围)阈值。因此,当一个块包含超过5个连续且可滚动的变量时,TLC将折叠其中嵌套的行%卷而且% endroll形成一个循环。如果存在少于5个连续的可滚动变量,%卷不创建循环,而是生成单独的代码行。

这告诉TLC它正在操作块对象。s函数的TLC代码使用此参数。

“滚”

这在rtw / c / tlc / roller.tlc,格式化循环。通常情况下,您可以按原样传递它,但其他循环控制结构也可以用于高级用途(请参阅LibBlockInputSignal输入信号函数)。

rollVars

告诉TLC什么类型的物品应该滚动:输入信号,输出信号,和/或参数。你不需要全部使用它们。在前面一行中,rollVars定义为%分配

%assign rollVars = ["U", "Y"]
这个列表告诉TLC它正在滚动输入信号(U)和输出信号(Y)。在块指定参数数组而不是标量参数的情况下,rollvars指定为
%assign rollVars = ["U", "Y", "P"]

输入信号,输出信号和参数

看看中间出现的线条%卷而且% endroll

% = \ % * 2.0;

TLC库函数LibBlockInputSignal而且LibBlockOutputSignal展开以生成命名并建立索引的标量或向量标识符。LibBlockInputSignalLibBlockOutputSignal,并向一些相关的TLC函数传递四个规范参数:

论点 描述

〇第一个论点0

对应于给定块的输入端口索引。第一个输入端口的索引为0。第二个输入端口的索引为1,依此类推。

〇第二论点" "

为高级用途保留的索引变量。现在,将第二个参数指定为空字符串。在高级应用程序中,可以定义自己的变量名作为索引%卷.在这种情况下,TLC将该变量声明为生成代码中某个位置的整数。

第三个论点液位控制阀

如前所述,lcv = RollThreshold设置在%卷表示每当构造一个循环时RollThreshold(默认值为5)。

第四个论点sigIdx

使TLC处理特殊情况。万一RollThreshold超过(例如,如果块仅连接到标量输入信号)TLC不会将其滚入循环。相反,TLC在相应的“内联”代码行中为索引变量提供一个整数值。每当RollThreshold, TLC产生循环并使用索引变量访问循环中的输入、输出和参数。

相关的话题