Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

リリース間ワークフローを使用した生成コードの統合

この例では、リリース間ソフトウェアインザループ (SIL) ブロックを作成し、ブロックを統合モデル内に組み込んで以前に生成したコードを再使用する方法を示します。ワークフローの詳細については、リリース間のコード統合を参照してください。

モデルからのコードの生成

リリース間コード統合ワークフローで、以前に生成したコードからソフトウェアインザループ (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 15.015s

生成コードが含まれるビルド フォルダーを特定します。

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/R2023b:

    rtwtypes.h

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

コードのインポート

統合モデルを読み込みます。

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_R2023b
### Starting build process for SIL block: CrossReleaseCounter_R2023b

統合モデルへのリリース間 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_R2023b_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_R2023b_sil
### Application stopped
### Stopping SIL simulation for component: CrossReleaseCounter_R2023b_sil

パラメーターの調整

リリース間 SIL ブロックのソース モデルは 2 つの調整可能なパラメーターを参照します。これらのパラメーターは、ベース ワークスペースで 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_R2023b_sil
### Application stopped
### Stopping SIL simulation for component: CrossReleaseCounter_R2023b_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 22.971s

インポートしたコードに対する呼び出しの確認

統合モデル コード内のリリース間ブロック コードを確認するには、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_R2023b_sil does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 15.921s
### 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