matlab缓冲区设置,使用 Simulink.Signal 对象指定缓冲区重用

示例模型

模型 rtwdemo_reusable_csc 包含不可重用的子系统 DeltaSubsystem 和 MATLAB Function 模块 Downsample。DeltaSubsystem 包含 MATLAB Function 模块 DeltaX 和 DeltaY。

model ='rtwdemo_reusable_csc';

open_system(model);

8563ca245f7d5758c9a24f24347c0a37.png

配置 Simulink 信号对象以实现重用

在 Apps 库中,在 Code generation 下,点击 Embedded Coder。C Code 选项卡将打开。

要打开 Code Mappings 编辑器,请点击 Code Interface > Individual Element Code Mappings。

在模型中,选择 RCSC_REAL 信号线。要在 Code Mappings 编辑器中查看此信号或任何信号,请在 Signals/States 选项卡上,点击 Add selected signals to code mappings 按钮。

对于表示信号线的行,检查 Storage Class 列。信号对象使用存储类 Reusable,这意味着该对象作为名为 RCSC_REAL 的全局变量出现在生成的代码中。

在模型中,导航到 DeltaSubsystem 子系统中。

在该子系统中选择 RCSC_REAL 信号线。此信号也解析为基础工作区中的信号对象。

使用 Reusable 存储类时,生成的代码可以将 Complex to Real-Imag 模块(在模型的根级别)的输出和 DeltaX 模块(在子系统中)的输出存储在 RCSC_REAL 全局变量中。

生成代码

编译模型。

currentDir = pwd;

[~,cgDir] = rtwdemodir();

rtwbuild(model);

### Starting build procedure for: rtwdemo_reusable_csc

### Successful completion of build procedure for: rtwdemo_reusable_csc

Build Summary

Top model targets built:

Model Action Rebuild Reason

=====================================================================================================

rtwdemo_reusable_csc Code generated and compiled Code generation information file does not exist.

1 of 1 models built (0 models already up to date)

Build duration: 0h 0m 24.041s

对于缓冲区重用,rtwdemo_reusable_csc.c 文件包含以下全局变量:

static real_T RCSC_IMAG[1048576];

static real_T RCSC_IMAG2[262144];

static real_T RCSC_REAL[1048576];

static real_T RCSC_REAL2[262144];

rtwdemo_reusable_csc.c 文件包含以下代码:

cfile = fullfile(cgDir,...

'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c');

rtwdemodbtype(cfile,...

'/* Output and update for atomic system: ''/DeltaSubsystem'' */',...

'/* Output and update for atomic system: ''/Downsample'' */',1,0);

rtwdemodbtype(cfile,...

'/* Model step function */','/* Model initialize function */',1,0);

/* Output and update for atomic system: '/DeltaSubsystem' */

static void DeltaSubsystem(void)

{

/* SignalConversion generated from: '/DeltaX' incorporates:

* MATLAB Function: '/DeltaX'

*/

DeltaX((&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0])), (&(RCSC_REAL[0])),

(&(RCSC_IMAG[0])));

/* SignalConversion generated from: '/DeltaY' incorporates:

* MATLAB Function: '/DeltaY'

*/

DeltaY((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),

(&(RCSC_IMAG2[0])));

}

/* Model step function */

void rtwdemo_reusable_csc_step(void)

{

int32_T i;

/* ComplexToRealImag: '/Complex to Real-Imag' incorporates:

* Inport: '/ComplexData'

*/

for (i = 0; i < 1048576; i++) {

RCSC_REAL[i] = rtU.ComplexData[i].re;

RCSC_IMAG[i] = rtU.ComplexData[i].im;

}

/* End of ComplexToRealImag: '/Complex to Real-Imag' */

/* MATLAB Function: '/Downsample' */

Downsample((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),

(&(RCSC_IMAG2[0])));

/* Outputs for Atomic SubSystem: '/DeltaSubsystem' */

DeltaSubsystem();

/* End of Outputs for SubSystem: '/DeltaSubsystem' */

/* Outport: '/Out1' incorporates:

* RealImagToComplex: '/Real-Imag to Complex'

* SignalConversion generated from: '/DeltaY'

* */

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 to Real-Image 模块和 DeltaX 的输出。它们还是 DeltaY 模块的输入。变量 RCSC_REAL2 和 RCSC_IMAG2 是 Downsample 和 DeltaY 的输出。它们还是 DeltaX 模块的输入。通过这种交错缓冲区的方式,消除了生成代码中的全局变量。

要从信号线删除信号对象并重新生成代码,请在 MATLAB 命令行窗口中输入以下命令:

portHandles = get_param(...

'rtwdemo_reusable_csc/Complex to Real-Imag','portHandles');

set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');

set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...

'rtwdemo_reusable_csc/Downsample','portHandles');

set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');

set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...

'rtwdemo_reusable_csc/DeltaSubsystem/DeltaX','portHandles');

set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');

set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

portHandles = get_param(...

'rtwdemo_reusable_csc/DeltaSubsystem/DeltaY','portHandles');

set_param(portHandles.Outport(1),'MustResolveToSignalObject','off');

set_param(portHandles.Outport(2),'MustResolveToSignalObject','off');

rtwbuild(model);

### Starting build procedure for: rtwdemo_reusable_csc

### Successful completion of build procedure for: rtwdemo_reusable_csc

Build Summary

Top model targets built:

Model Action Rebuild Reason

====================================================================================

rtwdemo_reusable_csc Code generated and compiled Generated code was out of date.

1 of 1 models built (0 models already up to date)

Build duration: 0h 0m 19.023s

rtwdemo_reusable_csc.c 文件现在包含以下代码。

cfile = fullfile(cgDir,...

'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c');

rtwdemodbtype(cfile,...

'/* Output and update for atomic system: ''/DeltaSubsystem'' */',...

'/* Output and update for atomic system: ''/Downsample'' */',1,0);

rtwdemodbtype(cfile,...

'/* Model step function */','/* Model initialize function */',1,0);

/* Output and update for atomic system: '/DeltaSubsystem' */

static void DeltaSubsystem(void)

{

/* MATLAB Function: '/DeltaX' */

DeltaX(rtDWork.z2, rtDWork.z1, rtDWork.z1_m, rtDWork.z2_c);

/* MATLAB Function: '/DeltaY' */

DeltaY(rtDWork.z1_m, rtDWork.z2_c, &rtDWork.z1[0], &rtDWork.z2[0]);

}

/* Model step function */

void rtwdemo_reusable_csc_step(void)

{

int32_T i;

/* ComplexToRealImag: '/Complex to Real-Imag' incorporates:

* Inport: '/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' */

}

生成的代码会包含两个用于存放模块输入和输出的新增全局变量。

注意:您可以对代码生成器不能实现的信号指定缓冲区重用。对于这些情况,请使用两个诊断来指定模型显示的消息类型。在 Configuration Parameters 对话框中,这两个诊断分别为 Detect non-reused custom storage classes 和 Detect ambiguous custom storage class final values。

bdclose(model)

rtwdemoclean;

cd(currentDir)

Unit Delay 和 Delay 模块的缓冲区重用

要重用 Unit Delay 或 Delay 模块的信号,请对 Unit Delay 或 Delay 模块中的输入和状态参数对组或输出和状态参数对组,使用相同的可重用存储类设定。对于 Delay 模块,必须将 Delay length 参数设置为 1,将 Initial condition > Source 参数设置为 Dialog。要访问这些参数,请在模型中打开 Property Inspector,然后点击模型中的模块。

根级输入输出端口信号的限制

对于为根级输入输出端口信号对组指定了缓冲区重用的模型而言,需遵循以下限制:

输出端口不能是条件输出端口。

如果代码生成器不能在顶层模型中重用同一缓冲区,则生成代码中将包含额外的缓冲区。如果顶层模型是引用模型,则代码生成器会报错。要修复错误,需从连接到输出端口的信号中删除 Simulink.signal 设定。

当您运行代码生成器生成的可执行文件并重用根级输入输出端口信号对组时,如果根级输入值为零,则根级输出值也必须为零。如果您在输出值不为零时重用信号,则仿真执行结果可能与可执行文件产生的结果有所不同。

当您将同一 Reusable 存储类分配给根输入端口和根输出端口信号对组时,可能会出现仿真与代码生成不匹配的情况。当 Assignment 模块驱动 Root Outport 模块且 Assignment 模块没有为输出信号的每个元素赋值时,就会发生这种不匹配,因为 Assignment 模块的 Y0 端口未处于活动状态。下图显示了一个出现不匹配情况的模型:

a554b109c5963ab3929b0103ce5a35f0.png

在仿真过程中,未写入的 Assignment 模块的输出值为零。在代码生成过程中,未写入的输出值与输入值相同。

对模型的限制

对于为信号指定了缓冲区重用的模型,需遵循以下限制:

您指定的重用信号必须具有相同的数据类型和采样率。

对于用户指定的缓冲区重用,在执行模块时,必须先执行那些对指定的重用信号进行修改的模块,后执行那些使用原始信号值的模块。有时,代码生成器必须更改模块的执行顺序,才能使缓冲区重用正常工作。对于代码生成器不能调整模块执行顺序的模型,缓冲区重用将不起作用。

对于代码生成器可调整模块执行顺序从而使 Simulink.Signal 重用能够正常工作的模型,您可以观察其模块执行顺序的差异。在 Debug 选项卡的 Diagnostics 部分中,选择 Information Overlays 下拉箭头。在对话框的 Blocks 部分中,选择 Execution Order。要在仿真期间显示经过排序的执行顺序,请在 Modeling 选项卡上,选择 Update Model。要在生成的代码中显示执行顺序,请在 C Code 选项卡上,选择 Build Model。

您可以为一系列可重用子系统指定缓冲区重用,前提是这些子系统不会在模型中的任何位置重用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值