Main Content

Simulink.Signal オブジェクトを使用したバッファーの再利用の指定

データ コピーの削除に最適なパラメーター設定がモデルに存在する場合は、Simulink.Signal オブジェクトを使用してバッファーの再利用を指定することで、追加のデータ コピーを削除できる可能性があります。生成コードと静的コード メトリクス レポートを調査し、バッファーの再利用が可能であると思われる領域を特定した後で、信号線上の信号オブジェクトを指定します。

ルート Inport 信号とルート Outport 信号のペアを含む信号でバッファーの再利用を指定できます。1 ペアのルート Inport 信号とルート Outport 信号に対してバッファーの再利用を指定することもできます。この最適化によって、生成コード内のグローバル変数とデータ コピーの数が削減されるため、ROM と RAM の消費量が低減します。コードの実行速度も向上します。

モデル例

モデル rtwdemo_reusable_csc には再利用できないサブシステム DeltaSubsystem と MATLAB Function ブロック Downsample が含まれます。DeltaSubsystem には MATLAB Function ブロック DeltaXDeltaY が含まれます。

model ='rtwdemo_reusable_csc';
open_system(model);

再利用のための Simulink 信号オブジェクトの指定

  1. [アプリ] ギャラリーの [コード生成] で、[Embedded Coder] をクリックします。[C コード] タブが開きます。

  2. コード マッピング エディターを開くには、[コード インターフェイス][個々の要素コードのマッピング] をクリックします。

  3. モデルで RCSC_REAL 信号線を選択します。この信号またはコード マッピング エディター内の任意の信号を表示するには、[信号/状態] タブで [選択した信号をコード マッピングに追加] ボタンをクリックします。

  4. 信号線を表す行の [ストレージ クラス] 列を検証します。この信号オブジェクトではストレージ クラス Reusable が使用されています。これは、オブジェクトが生成コードに RCSC_REAL という名前のグローバル変数として表示されることを意味します。

  5. モデルで DeltaSubsystem サブシステム内に移動します。

  6. このサブシステム内の 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: ''<Root>/DeltaSubsystem'' */',...
    '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0);
rtwdemodbtype(cfile,...
    '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
  /* SignalConversion generated from: '<S1>/DeltaX' incorporates:
   *  MATLAB Function: '<S1>/DeltaX'
   */
  DeltaX((&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0])), (&(RCSC_REAL[0])),
         (&(RCSC_IMAG[0])));

  /* SignalConversion generated from: '<S1>/DeltaY' incorporates:
   *  MATLAB Function: '<S1>/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: '<Root>/Complex to Real-Imag' incorporates:
   *  Inport: '<Root>/ComplexData'
   */
  for (i = 0; i < 1048576; i++) {
    RCSC_REAL[i] = rtU.ComplexData[i].re;
    RCSC_IMAG[i] = rtU.ComplexData[i].im;
  }

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

  /* MATLAB Function: '<Root>/Downsample' */
  Downsample((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),
             (&(RCSC_IMAG2[0])));

  /* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
  DeltaSubsystem();

  /* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */

  /* Outport: '<Root>/Out1' incorporates:
   *  RealImagToComplex: '<Root>/Real-Imag to Complex'
   *  SignalConversion generated from: '<S1>/DeltaY'
   * */
  for (i = 0; i < 261121; i++) {
    rtY.Out1[i].re = RCSC_REAL2[i];
    rtY.Out1[i].im = RCSC_IMAG2[i];
  }

  /* End of Outport: '<Root>/Out1' */
}

変数 RCSC_REALRCSC_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: ''<Root>/DeltaSubsystem'' */',...
    '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0);
rtwdemodbtype(cfile,...
    '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
  /* MATLAB Function: '<S1>/DeltaX' */
  DeltaX(rtDWork.z2, rtDWork.z1, rtDWork.z1_m, rtDWork.z2_c);

  /* MATLAB Function: '<S1>/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: '<Root>/Complex to Real-Imag' incorporates:
   *  Inport: '<Root>/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: '<Root>/Complex to Real-Imag' */

  /* MATLAB Function: '<Root>/Downsample' */
  Downsample(rtDWork.RCSC_REAL, rtDWork.RCSC_IMAG, rtDWork.z2, rtDWork.z1);

  /* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
  DeltaSubsystem();

  /* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */

  /* Outport: '<Root>/Out1' incorporates:
   *  RealImagToComplex: '<Root>/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: '<Root>/Out1' */
}

生成コードには、ブロック入力と出力を格納する追加のグローバル変数が 2 つ含まれます。

メモ: コード ジェネレーターでは実装できないバッファーの再利用を信号に指定できます。このような場合は、2 つの診断を使用して、モデルに表示されるメッセージのタイプを指定します。これらの診断は、[コンフィギュレーション パラメーター] ダイアログ ボックスの [再利用されないカスタム ストレージ クラスを検出][あいまいなカスタム ストレージ クラスの最終値を検出] です。

bdclose(model)
rtwdemoclean;
cd(currentDir)

Unit Delay ブロックや Delay ブロックのためのバッファー再利用

Unit Delay ブロックまたは Delay ブロックの信号を再利用するには、Unit Delay ブロックまたは Delay ブロックの入力引数と状態引数のペア、または出力引数と状態引数のペアに対して、再利用可能なストレージ クラスの同じ仕様を使用します。Delay ブロックでは、[遅延の長さ] パラメーターを 1 に設定し、[初期条件]、[ソース] を [Dialog] に設定しなければなりません。これらのパラメーターにアクセスするには、モデル内でプロパティ インスペクターを開き、モデル内のブロックをクリックします。

ルート Inport 信号とルート Outport 信号に関する制限

ルート Inport 信号とルート Outport 信号のペアに対してバッファー再利用を指定したモデルには、以下の制限が適用されます。

  • 出力端子を条件付きにすることはできません。

  • コード ジェネレーターが最上位モデルで同じバッファーを再利用できない場合、生成されたコードには追加のバッファーが含まれます。最上位モデルが参照モデルである場合、コード ジェネレーターはエラーを報告します。このエラーを解決するには、Outport 端子に接続された信号から Simulink.signal の指定を削除します。

  • コード ジェネレーターによって作成された実行可能ファイルを実行し、ルート Inport 信号とルート Outport 信号のペアを再利用する場合、ルート入力値がゼロのときはルート出力値もゼロでなければなりません。出力値が非ゼロで、信号を再利用する場合、シミュレーションの結果は実行可能ファイルで生成される結果と異なる可能性があります。

  • ルート Inport 信号とルート Outport 信号のペアに同じ再利用可能なストレージ クラスを割り当てると、シミュレーションとコード生成間に不一致が生じる可能性があります。Assignment ブロックの Y0 端子はアクティブではないため、この不一致は、Assignment ブロックが Root Outport ブロックを駆動し、Assignment ブロックが出力信号のすべての要素に値を割り当てない場合に発生します。この図に、不一致が生じるモデルを示します。

シミュレーション時に、書き込まれていない Assignment ブロックの出力値はゼロです。コード生成時に、書き込まれていない出力値は入力と同じです。

モデルに関する制限

信号に対してバッファー再利用を指定したモデルには、以下の制限が適用されます。

  • 再利用を指定した信号のデータ型およびサンプル レートは同じでなければなりません。

  • ユーザー指定のバッファー再利用については、再利用に指定された信号を変更するブロックは元の信号値を使用するブロックより前に実行されなければなりません。場合によっては、コード ジェネレーターはバッファー再利用が行われるようにブロック演算の順序を変更する必要があります。コード ジェネレーターがブロック演算を並べ替えることができないモデルの場合、バッファー再利用は行われません。

  • Simulink.Signal の再利用が行われるようにコード ジェネレーターがブロック演算を並べ替えるモデルの場合、並べ替え順序に違いがあることを確認できます。[デバッグ] タブの [診断] セクションで、[情報のオーバーレイ] ドロップダウン矢印を選択します。ダイアログの [ブロック] セクションで、[実行順序] を選択します。シミュレーション中のソートされた実行順序を表示するには、[モデル化] タブで [モデルの更新] を選択します。生成コードでの実行順序を表示するには、[C コード] タブで [モデルのビルド] を選択します。

  • モデル内のどの場所でも再利用されない場合に限り、一連の再利用可能なサブシステムに対してバッファーの再利用を指定できます。

関連するトピック