Main Content

使用跨版本工作流集成生成的代码

此示例说明如何通过创建跨版本软件在环 (SIL) 模块并将该模块整合到集成模型中来重用以前生成的代码。有关工作流的详细信息,请参阅 Cross-Release Code Integration

从模型中生成代码

在跨版本代码集成工作流中,您可以从以前生成的代码创建一个软件在环 (SIL) 或处理器在环 (PIL) 模块。

此示例使用从当前版本中生成的代码。

model = 'CrossReleaseCounter';
close_system(model,0)
load_system(model)
set_param(model, 'SimulationCommand', 'update');
open_system(model)
slbuild(model);
### Starting build procedure for: CrossReleaseCounter
### Successful completion of code generation for: CrossReleaseCounter

Build Summary

Top model targets built:

Model                Action           Rebuild Reason                                    
========================================================================================
CrossReleaseCounter  Code generated.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.4369s

标识包含生成代码的编译文件夹。

buildFolder = RTW.getBuildDir(model).BuildDirectory;

标识包含与生成的代码相关联的共享实用工具代码的文件夹。

previousSharedCodeFolder = RTW.getBuildDir(model).SharedUtilsTgtDir;

要重用以前版本中生成的代码,请执行以下操作:

  1. 仿真选项卡的文件部分中,选择保存 > 以前的版本

  2. 另存为类型字段中,指定版本和模型类型。

  3. 点击保存

  4. 使用以前的版本打开保存的模型,然后生成代码。

  5. buildFolder 的值设置为上一版本中生成的代码的位置。

  6. previousSharedCodeFolder 的值设置为上一版本中生成的共享实用工具的位置。

管理共享代码

将生成的共享源代码文件添加到集成模型使用的存储库文件夹中。

sharedCodeRepo = 'SharedCodeRepo';
mkdir(sharedCodeRepo);
sharedCodeUpdate(previousSharedCodeFolder, sharedCodeRepo, 'Interactive', false);
The following files will be copied from slprj/ert/_sharedutils to SharedCodeRepo/R2024a:

    rtwtypes.h

Files copied from slprj/ert/_sharedutils to SharedCodeRepo/R2024a.

导入代码

加载集成模型。

integrationModel = 'CrossReleaseIntegration';
close_system(integrationModel, 0);
load_system(integrationModel);

修改 Simulink 配置集,使其引用现有共享代码库。

cs = getActiveConfigSet(integrationModel);
set_param(cs, 'ExistingSharedCode', fullfile(pwd, sharedCodeRepo));

创建跨版本 SIL 模块。

blockHandle = crossReleaseImport(buildFolder, cs, 'SimulationMode', 'SIL');
### Starting import process for component: CrossReleaseCounter_R2024a
### Starting build process for SIL block: CrossReleaseCounter_R2024a

将跨版本 SIL 模块合并到集成模型中

要将集成模型中的模块替换为跨版本模块,请使用 pil_block_replace。此函数保留模块大小、信号线连接和优先级。

srcBlock = getfullname(blockHandle);
dstBlock = [integrationModel, '/', 'Counter'];
pil_block_replace(srcBlock, dstBlock)
open_system(integrationModel)
Successfully swapped the following blocks: 

untitled/CrossReleaseCounter_R2024a_sil
CrossReleaseIntegration/Counter


集成模型的仿真

运行集成模型的仿真。

sim(integrationModel)
### Preparing to start SIL block simulation: <a href="matlab: targets_hyperlink_manager('run',1);">CrossReleaseIntegration/Counter</a> ...
### Starting SIL simulation for component: CrossReleaseCounter_R2024a_sil
### Application stopped
### Stopping SIL simulation for component: CrossReleaseCounter_R2024a_sil

调整参数

跨版本 SIL 模块的源模型引用两个可调参数,这些参数由基础工作区中的 Simulink.Parameter 对象控制。使用这些参数修改 SIL 仿真的行为。

countUpper.Value = 30;
countLower.Value = 20;
yout_retuned = sim(integrationModel, 'ReturnWorkspaceOutputs', 'on');
### Preparing to start SIL block simulation: <a href="matlab: targets_hyperlink_manager('run',1);">CrossReleaseIntegration/Counter</a> ...
### Starting SIL simulation for component: CrossReleaseCounter_R2024a_sil
### Application stopped
### Stopping SIL simulation for component: CrossReleaseCounter_R2024a_sil

在集成模型中配置信号的存储类

配置:

  • 集成模型中的信号名称,以匹配在导入代码中使用的名称。

  • 补充存储类。

在本示例中,ticks 输入和 count 输出是通过导入的代码中的 ImportedExtern 存储类来实现的。如果连接到集成模型中跨版本模块的输入和输出端口的信号的存储类为 ExportedGlobal,则集成模型必须提供变量的定义。

如果信号名称不匹配,则集成模型将生成附加代码,以在由集成模型实现的信号和由导入的代码实现的信号之间复制数据。

hLines = get_param(dstBlock, 'LineHandles');

% Use the code mappings API to configure the storage class on the signals.
cm = coder.mapping.api.get(integrationModel);
ticksPortHandle = get(hLines.Inport(1), 'SrcPortHandle');
set(ticksPortHandle, 'Name', 'ticks');
addSignal(cm, ticksPortHandle);
setSignal(cm, ticksPortHandle, 'StorageClass', 'ExportedGlobal');

countPortHandle = get(hLines.Outport(1), 'SrcPortHandle');
set(countPortHandle, 'Name', 'count');
addSignal(cm, countPortHandle);
setSignal(cm, countPortHandle, 'StorageClass', 'ExportedGlobal');

在集成模型中配置参数和数据存储内存的存储类

参数和数据存储是通过导入的代码中的 ImportedExtern 存储类实现的。如果您将参数和数据存储配置为使用 ExportedGlobal 存储类,则集成模型必须提供变量的定义。

resetSignal.CoderInfo.StorageClass = 'ExportedGlobal';
countLower.CoderInfo.StorageClass = 'ExportedGlobal';
countUpper.CoderInfo.StorageClass = 'ExportedGlobal';

从集成模型中生成代码

在所需的共享代码保存到共享代码存储库中以后,请删除以前生成的共享实用工具文件夹。

if isfolder(RTW.getBuildDir(integrationModel).SharedUtilsTgtDir)
    rmdir(RTW.getBuildDir(integrationModel).SharedUtilsTgtDir, 's');
end

删除不影响代码生成的范围和连接线。

scopeBlock = [integrationModel, '/', 'Scope'];
hScopeLines = get_param(scopeBlock, 'LineHandles');
hScopeLine = hScopeLines.Inport(1);
assert(strcmp(get(hScopeLine, 'SegmentType'), 'branch'));
delete_line(hScopeLine);
delete_block(scopeBlock);

生成代码。

slbuild(integrationModel);
### Starting build procedure for: CrossReleaseIntegration
### Successful completion of code generation for: CrossReleaseIntegration

Build Summary

Top model targets built:

Model                    Action           Rebuild Reason                                    
============================================================================================
CrossReleaseIntegration  Code generated.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 12.391s

检查对导入代码的调用

要检查集成模型代码中的跨版本模块代码,请使用 rtwtrace 实用工具。

rtwtrace(dstBlock);

测试从集成模型生成的代码

运行集成模型的顶层模型软件在环 (SIL) 仿真。仿真运行从集成模型生成的代码,这会调用导入的代码。

将仿真输出记录在工作区中。

set_param(integrationModel, 'SimulationMode', 'software-in-the-loop (sil)');
yout_SIL = sim(integrationModel, 'ReturnWorkspaceOutputs', 'on');
plot(yout_SIL.yout{1}.Values);
### Starting build procedure for: CrossReleaseIntegration
### Successful completion of build procedure for: CrossReleaseIntegration

Build Summary

Top model targets built:

Model                    Action                        Rebuild Reason                                             
==================================================================================================================
CrossReleaseIntegration  Code generated and compiled.  S-function CrossReleaseCounter_R2024a_sil does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 10.406s
### Preparing to start SIL simulation ...
Building with 'gcc'.
MEX completed successfully.
### Updating code generation report with SIL files ...
### Starting SIL simulation for component: CrossReleaseIntegration
### Application stopped
### Stopping SIL simulation for component: CrossReleaseIntegration

比较仿真输出

比较以下两种仿真输出:在 SIL 模式下只运行导入代码的仿真输出,以及在 SIL 模式下作为顶层模型运行的集成模型的仿真输出。

max(abs(yout_SIL.yout{1}.Values.Data - yout_retuned.yout{1}.Values.Data))
ans =

  uint8

   0