Main Content

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

条件付きインクルード (#if / #endif)

モデルにバリアントを実装することで、コードにプリプロセッサの条件付き命令を生成できます。生成コードでは、プリプロセッサの条件付き命令により、実行するコードのセクションがコンパイル時に選択されます。

この例では、Simulink.Variant オブジェクトを使用して Variant Subsystem ブロックを制御します。バリアントを制御する他の方法の詳細については、Variant Control Modes in Variant Blocksを参照してください。Variant Subsystem ブロック以外のバリアントのタイプに関する詳細については、バリアントとは、およびどのような場合にそれを使用するかを参照してください。

モデルの検査

モデル例 PreprocessorConditionalsUsingVariantSubsystem を開きます。

model = 'PreprocessorConditionalsUsingVariantSubsystem';
open_system(model);

Capture.PNG

このモデルには、LeftController RightController という 2 つのバリアント サブシステムが含まれており、それぞれに 2 つの子サブシステム LinearNonlinear があります。モデルのコールバック関数 PostLoadFcnrtwdemo_preprocessor_data.mat が読み込まれます。コールバック関数を確認するには、Simulink ツールストリップで [モデル化] タブをクリックし、[設定] セクションで [モデル設定]、[モデル プロパティ] をクリックします。[モデル プロパティ] ダイアログ ボックスで [コールバック] タブを開き、[PostLoadFcn] を選択します。あるいは、プログラムでコールバック関数を確認します。

get_param(model,'PostLoadFcn')
ans = 
'load preprocessor_data.mat'

コールバック関数により、2 つの Simulink.Variant オブジェクト LINEAR および NONLINEAR と 1 つの Simulink.Parameter オブジェクト VSSMODE がインスタンス化されます。LINEAR バリアントは VSSMODE0 に等しい場合にアクティブになります。NONLINEAR バリアントは VSSMODE1 の場合にアクティブになります。VSSMODE1 に初期化されています。これらの設定をプログラムで確認します。

LINEAR.Condition
ans = 
'VSSMODE==0'
NONLINEAR.Condition
ans = 
'VSSMODE==1'
VSSMODE.Value
ans = int32
    1

LeftController および RightController では、それぞれのサブシステムである LinearNonlinear のバリアント制御式として LINEARNONLINEAR を使用しています。この構成を確認するには、LeftController を右クリックし、[ブロック パラメーター (Subsystem)] をクリックします。あるいは、プログラムでバリアント制御式を確認します。

choices = get_param(append(model,'/LeftController'),'VariantChoices');
choices(1)
ans = struct with fields:
         Name: 'LINEAR'
    BlockName: 'PreprocessorConditionalsUsingVariantSubsystem/LeftController/Linear'

choices(2)
ans = struct with fields:
         Name: 'NONLINEAR'
    BlockName: 'PreprocessorConditionalsUsingVariantSubsystem/LeftController/Nonlinear'

モデルの設定

[コンフィギュレーション パラメーター] ダイアログ ボックスを開きます。左側のペインで [コード生成] をクリックし、[システム ターゲット ファイル]ert.tlc に設定されていることを確認します。あるいは、プログラムでパラメーターを設定します。

set_param(model,'SystemTargetFile','ert.tlc');

左側のペインで [インターフェイス] をクリックします。Ignore custom storage classesパラメーターがオフになっていることを確認します。あるいは、プログラムでパラメーターをオフにします。

set_param(model,'IgnoreCustomStorageClasses','off');

プリプロセッサの条件を生成するには、カスタム ストレージ クラスを使用します。

LeftController サブシステムの [ブロック パラメーター] ダイアログ ボックスを開きます。Variant activation timeパラメーターが code compile に設定されていることを確認します。あるいは、プログラムでパラメーターを設定します。

set_param(append(model,'/LeftController'),'VariantActivationTime','code compile');

LeftController サブシステムを開きます。それぞれの子サブシステムについて、サブシステムをクリックし、[Subsystem ブロック] タブで [Atomic サブシステム] が選択されていることを確認します。あるいは、プログラムでパラメーターを設定します。

set_param(append(model,'/LeftController/Linear'),'TreatAsAtomicUnit','on');
set_param(append(model,'/LeftController/Nonlinear'),'TreatAsAtomicUnit','on');

コードを生成します。

slbuild(model);
### Starting build procedure for: PreprocessorConditionalsUsingVariantSubsystem
### Successful completion of build procedure for: PreprocessorConditionalsUsingVariantSubsystem

Build Summary

Top model targets built:

Model                                          Action                        Rebuild Reason                                    
===============================================================================================================================
PreprocessorConditionalsUsingVariantSubsystem  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 11.339s

生成されたコードを表示します。生成されたコードには、いずれのバリアントをコンパイルするかを選択するための LINEARNONLINEAR を使用した #if および #endif プリプロセッサ命令が含まれます。

cfile = fullfile('PreprocessorConditionalsUsingVariantSubsystem_ert_rtw','PreprocessorConditionalsUsingVariantSubsystem.c');
coder.example.extractLines(cfile,"  /* Outputs for Atomic SubSystem: '<Root>/LeftController' */", "  /* End of Outputs for SubSystem: '<Root>/LeftController' */", 1, 1);
  /* Outputs for Atomic SubSystem: '<Root>/LeftController' */
#if LINEAR

  /* Outputs for Atomic SubSystem: '<S1>/Linear' */
  /* VariantMerge generated from: '<S1>/Out1' incorporates:
   *  DiscreteFilter: '<S3>/Discrete Filter'
   */
  rtY.Out1 = rtb_Add - 0.5 * rtDWork.DiscreteFilter_states_a;

  /* Update for DiscreteFilter: '<S3>/Discrete Filter' */
  rtDWork.DiscreteFilter_states_a = rtY.Out1;

  /* End of Outputs for SubSystem: '<S1>/Linear' */
#elif NONLINEAR

  /* Outputs for Atomic SubSystem: '<S1>/Nonlinear' */
  /* VariantMerge generated from: '<S1>/Out1' incorporates:
   *  DiscreteFilter: '<S4>/Discrete Filter'
   *  Lookup_n-D: '<S4>/Lookup Table'
   *  Sum: '<Root>/Add'
   */
  rtY.Out1 = look1_binlxpw(rtb_Add, rtCP_LookupTable_bp01Data,
    rtCP_LookupTable_tableData, 4U) - 0.5 * rtDWork.DiscreteFilter_states_o;

  /* Update for DiscreteFilter: '<S4>/Discrete Filter' */
  rtDWork.DiscreteFilter_states_o = rtY.Out1;

  /* End of Outputs for SubSystem: '<S1>/Nonlinear' */
#endif

関連するトピック