为路径中的信号指定缓冲区重用
方法可以删除其他数据副本,如果模型具有用于删除数据副本的最佳参数设置可重用的
通过代码映射编辑器或金宝app仿真软件。信号
数据对象。这种优化减少了数据副本和内存消耗,并提高了代码执行速度。在研究生成的代码和静态代码度量报告并确定缓冲区重用可能的领域之后,您可以指定可重用的
信号线上的存储类。
您可以在包含一对根输入和输出信号的信号上指定缓冲区重用。您还可以仅在一对根输入和输出信号上指定缓冲区重用。这种优化减少了ROM和RAM的消耗,因为生成的代码中的全局变量和数据副本更少。代码执行速度也提高了。
示例模型
该模型ex_reusable_csc
包含不可重用的子系统DeltaSubsystem
MATLAB函数块Downsample
.DeltaSubsystem
包含MATLAB函数块△
而且δy
.
模型=“ex_reusable_csc”;open_system(模型);
在代码映射编辑器中指定可重用存储类
打开嵌入式编码器应用程序。
要打开代码映射编辑器,请单击代码接口>单个元素代码映射.
在模型中,选择
RCSC_REAL
线信号。要在“代码映射”编辑器中查看此信号或任何信号,请在信号/州选项卡,单击将选定的信号添加到代码映射中按钮。对于表示信号线的行,设置存储类列
可重用的
.类似地,将这些信号添加到代码映射编辑器并设置存储类来
可重用的
:
RCSC_IMAG
RCSC_REAL2
RCSC_IMAG2
子系统内部的这些信号:
RCSC_REAL
RCSC_IMAG
RCSC_REAL2
RCSC_IMAG2
或者,在MATLAB®命令窗口中使用这些命令:
Cmo = code .mapping.utils.create(model);Cm = code .mapping.api.get(model);portandles = get_param(...'ex_reusable_csc/Complex to real - image ',“portHandles”);addSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)),...“StorageClass”,可重用的);portandles = get_param(...“ex_reusable_csc / Downsample”,“portHandles”);addSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)),...“StorageClass”,可重用的);portandles = get_param(...“ex_reusable_csc / DeltaSubsystem /△”,“portHandles”);addSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)),...“StorageClass”,可重用的);portandles = get_param(...“ex_reusable_csc / DeltaSubsystem /δy”,“portHandles”);addSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)),...“StorageClass”,可重用的);
构建模型。
currentDir = pwd;[~,cgDir] = rtwdemodir();slbuild(模型);
# # #开始构建过程:ex_reusable_csc # # #成功完成构建过程:ex_reusable_csc模型建立目标:总结构建模型重建行动的理由 ================================================================================================= ex_reusable_csc代码生成和编译。代码生成信息文件不存在。构建1 / 1模型(0个模型已经更新)构建时间:0h 0m 15.375s
对于缓冲区重用,使用ex_reusable_csc.c
文件包含以下全局变量:
cfile = fullfile(cgDir,...“ex_reusable_csc_ert_rtw”,“ex_reusable_csc.c”);rtwdemodbtype(用...'/*自定义存储类的定义:可重用*/',...'/*外部输入(默认存储的根输入信号)*/'1 0);
/*自定义存储类:Reusable */ static real_T RCSC_IMAG[1048576];/* '<根>/Complex to real - image ' */ static real_T RCSC_IMAG2[262144];/* '/Downsample' */ static real_T RCSC_REAL[1048576];/* ' /Complex to real - image ' */ static real_T RCSC_REAL2[262144];/* '<根>/Downsample' */
的ex_reusable_csc.c
文件包含以下代码:
cfile = fullfile(cgDir,...“ex_reusable_csc_ert_rtw”,“ex_reusable_csc.c”);rtwdemodbtype(用...'/*输出和更新原子系统:" <根>/DeltaSubsystem " */',...'/*输出和更新原子系统:" <根>/Downsample " */'1 0);rtwdemodbtype(用...'/*模型阶跃函数*/',/*模型初始化函数*/1 0);
/*输出和更新原子系统:'<根>/DeltaSubsystem' */静态void DeltaSubsystem(void) {/* ComplexToRealImag: '<根>/Complex to Real-Imag'合并:* MATLAB函数:'/DeltaX' *信号转换生成从:' /DeltaX' * */ DeltaX(&RCSC_REAL2[0], &RCSC_IMAG2[0], &RCSC_REAL[0], &RCSC_IMAG[0]);/*信号转换生成自:'<根>/Downsample'合并:* ComplexToRealImag: '<根>/Complex to Real-Imag' * MATLAB函数:' /DeltaY' *信号转换生成自:' /DeltaY' * */ DeltaY(&RCSC_REAL[0], &RCSC_IMAG[0], &RCSC_REAL2[0], &RCSC_IMAG2[0]);} /*模型步长函数*/ void ex_reusable_csc_step(void) {int32_T i;/* ComplexToRealImag: '<根>/Complex to Real-Imag' contains: * import: '<根>/ComplexData' */ for (i = 0;I < 1048576;{RCSC_REAL[i] = rtU.ComplexData[i].re;RCSC_IMAG[i] = rtU.ComplexData[i].im;} /* End of ComplexToRealImag: ' /Complex to Real-Imag' */ /* MATLAB函数:' /Downsample' */ Downsample(&RCSC_REAL[0], &RCSC_IMAG[0], &RCSC_REAL2[0], &RCSC_IMAG2[0]);/*原子子系统的输出:'<根>/DeltaSubsystem' */ DeltaSubsystem();/*输出子系统:'<根>/DeltaSubsystem' */ /*输出端口:'<根>/Out1'合并:* RealImagToComplex: '<根>/ real - image to Complex' *信号转换生成自:' / delta ' * */ for (i = 0; i < 261121; i++) { rtY.Out1[i].re = RCSC_REAL2[i]; rtY.Out1[i].im = RCSC_IMAG2[i]; } /* End of Outport: ' /Out1' */ }
的变量RCSC_REAL
而且RCSC_IMAG
保持Complex到实像块的输出和△
.的输入δy
块。的变量RCSC_REAL2
而且RCSC_IMAG2
保持输出Downsample
而且δy
.的输入△
块。通过以这种方式交错缓冲区,可以消除生成代码中的冗余数据副本。
要从“代码映射”编辑器中删除信号,请在信号/州选项卡,选择信号并单击移除所选信号到代码映射按钮。
或者,在MATLAB命令窗口中使用这些命令:
portandles = get_param(...'ex_reusable_csc/Complex to real - image ',“portHandles”);removeSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)));portandles = get_param(...“ex_reusable_csc / Downsample”,“portHandles”);removeSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)));portandles = get_param(...“ex_reusable_csc / DeltaSubsystem /△”,“portHandles”);removeSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)));portandles = get_param(...“ex_reusable_csc / DeltaSubsystem /δy”,“portHandles”);removeSignal(厘米,[portHandles.Outport (1) portHandles.Outport (2)));
在为模型生成代码时,ex_reusable_csc.h
包含两个额外的全局变量:
slbuild(模型);cfile = fullfile(cgDir,...“ex_reusable_csc_ert_rtw”,“ex_reusable_csc.h”);rtwdemodbtype(用.../*阻塞信号和状态,...“}D_Work;”1 0);
# # #开始构建过程:ex_reusable_csc # # #成功完成构建过程:ex_reusable_csc模型建立目标:总结构建模型重建行动的理由 ================================================================================ ex_reusable_csc代码生成和编译。生成的代码已经过时。构建时间:0h 0m 11.367s /* Block信号和状态(默认存储)for system '' */ typedef struct {real_T z2[262144];/* ' /DeltaY' */ real_T z1[262144];/* ' /DeltaY' */ real_T z1_m[261632];/* ' /DeltaX' */ real_T z2_c[261632];/* ' /DeltaX' */ real_T RCSC_REAL[1048576];/* '<根>/Complex to Real-Imag' */ real_T RCSC_IMAG[1048576];/* '<根>/Complex to real - image ' */
的ex_reusable_csc.c
文件现在包含这段代码。
cfile = fullfile(cgDir,...“ex_reusable_csc_ert_rtw”,“ex_reusable_csc.c”);rtwdemodbtype(用...'/*输出和更新原子系统:" <根>/DeltaSubsystem " */',...'/*输出和更新原子系统:" <根>/Downsample " */'1 0);rtwdemodbtype(用...'/*模型阶跃函数*/',/*模型初始化函数*/1 0);
/*输出和更新原子系统:'<根>/DeltaSubsystem' */静态void DeltaSubsystem(void) {/* MATLAB函数:'/DeltaX' */ DeltaX(rtDWork. txt)z2, rtDWork。z1, rtDWork。z1_m rtDWork.z2_c);/* MATLAB函数:' /DeltaY' */ DeltaY(rtDWork。z1_m rtDWork。z2_c &rtDWork。z1 [0], &rtDWork.z2 [0]);} /*模型步长函数*/ void ex_reusable_csc_step(void) {int32_T i;/* ComplexToRealImag: '<根>/Complex to Real-Imag' contains: * import: '<根>/ComplexData' */ for (i = 0;I < 1048576;i++) {rtDWork。RCSC_REAL[i] = rtU.ComplexData[i].re; rtDWork.RCSC_IMAG[i] = rtU.ComplexData[i].im; } /* End of ComplexToRealImag: ' /Complex to Real-Imag' */ /* MATLAB Function: ' /Downsample' */ Downsample(rtDWork.RCSC_REAL, rtDWork.RCSC_IMAG, rtDWork.z2, rtDWork.z1); /* Outputs for Atomic SubSystem: ' /DeltaSubsystem' */ DeltaSubsystem(); /* End of Outputs for SubSystem: ' /DeltaSubsystem' */ /* Outport: ' /Out1' incorporates: * RealImagToComplex: ' /Real-Imag to Complex' */ for (i = 0; i < 261121; i++) { rtY.Out1[i].re = rtDWork.z1[i]; rtY.Out1[i].im = rtDWork.z2[i]; } /* End of Outport: ' /Out1' */ }
生成的代码包含两个额外的全局变量,用于保存块输入和输出。
在代码映射编辑器中使用可重用存储类的模型的限制
对于重用的数据元素,可以为标识符财产。属性的值标识符,代码生成器使用相同的信号标签来命名所生成代码中的可重用信号。代码生成器不重用信号,如果:
信号有相同的标签但不同的标识符。
信号具有相同的标识符,但这些属性的值不同:DataScope,HeaderFile,DefinitionFile,老板.如果在任何属性中存在不匹配,代码生成器将停止并在模型配置参数中产生错误检测非重用的自定义存储类设置为
错误
.
指定一个Simuli金宝appnk信号对象以供重用
1.打开模型rtwdemo_reusable
.
模型=“rtwdemo_reusable_csc”;open_system(模型);
2.模型中的信号分解为相应的金宝app仿真软件。信号
基本工作区中的数据对象。右键单击RCSC_REAL
线信号。从上下文菜单中选择属性.在“信号属性”对话框中,检查信号名称是否为RCSC_REAL
还有参数信号名称必须解析为Simulink信号对象金宝app被选中。此设置表示存在金宝app仿真软件。信号
的数据对象RCSC_REAL
.
3.模型中,导航到DeltaSubsystem
子系统。选择RCSC_REAL
该子系统的信号线。该信号还解析为基本工作区中的信号对象。
4.在Base Workspace中,双击该数据对象RCSC_REAL
.的金宝app仿真软件。信号
对话框。
5.在代码生成Tab,检查存储类参数设置为可重用的
.此设置指示代码生成器为信号生成命名为全局变量的代码RCSC_REAL
.与可重用的
存储类,生成的代码可以存储Complex to real - image块的输出(在模型的根级)和MATLAB Function块的输出△
(在子系统中)RCSC_REAL
全局变量。
6.在应用程序画廊,下代码生成,点击嵌入式编码器.的C代码选项卡打开。
7.单击构建按钮。
生成的代码实现了与前面工作流相同的结果,其中您将信号添加到code Mappings编辑器并设置存储类来可重用的
.
注意:可以对代码生成器无法实现的信号指定缓冲区重用。对于这些情况,使用两个诊断来指定模型显示的消息类型。在“配置参数”对话框中,这些诊断为检测非重用的自定义存储类而且检测不明确的自定义存储类最终值.
bdclose rtwdemoclean(模型);cd (currentDir)
单位延迟和延迟块的缓冲区重用
要重用单元延迟或延迟块的信号,请对单元延迟或延迟块的一对输入和状态参数或一对输出和状态参数使用相同的可重用存储类规范。对于延迟块,必须设置延迟的长度参数1
而且初始条件>源来对话框
.要在模型中访问这些参数,请打开Property Inspector并单击模型中的块。
根输入和输出信号的限制
这些限制适用于为一对根输入和输出信号指定缓冲区重用的模型:
输出端口不能有条件。
如果代码生成器不能在顶级模型中重用相同的缓冲区,则生成的代码将包含额外的缓冲区。如果顶部模型是一个引用模型,代码生成器将报告一个错误。若要解决此错误,请删除
金宝app仿真软件。信号
来自连接到输出端口的信号的规范。当您运行代码生成器生成的可执行文件,并重用一对根输入和输出信号时,当根输入值为零时,根输出值也必须为零。如果输出值是非零,并且您重用了信号,那么模拟的结果可能与可执行程序产生的结果不同。
当将相同的可重用存储类分配给一对根输入和根输出信号时,可能会出现模拟与代码生成不匹配的情况。当一个赋值块驱动根输出端口块,并且赋值块没有给输出信号的每个元素赋值时,这种不匹配就会发生,因为赋值块的Y端口不是活动的。下图显示了不匹配发生的模型:
在模拟过程中,未写入的赋值块输出值为零。在代码生成过程中,未写入的输出值与输入值相同。
使用Simulink信号对象的模型的局限性金宝app
类指定信号的缓冲区重用时,这些限制适用于该模型金宝app仿真软件。信号
数据对象:
指定用于重用的信号必须具有相同的数据类型和采样率。
对于用户指定的缓冲区重用,修改指定用于重用的信号的块必须在使用原始信号值的块之前执行。有时代码生成器必须改变块操作顺序,这样才能实现缓冲区重用。对于代码生成器无法对块操作重新排序的模型,缓冲区重用不会发生。
对于代码生成器重新排序块操作的模型
金宝app仿真软件。信号
可以发生重用,可以观察排序顺序的差异。在调试选项卡,在诊断部分选择信息覆盖下拉箭头。在块对话框的部分,选择执行顺序.控件上显示模拟过程中已排序的执行顺序建模选项卡上,选择更新模型.控件上显示所生成代码中的执行顺序C代码选项卡上,选择构建模型.您可以为可重用子系统链指定缓冲区重用,只要这些子系统在模型中的任何地方都没有被重用。