このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
条件付きインクルード (#if / #endif)
モデルにバリアントを実装することで、コードにプリプロセッサの条件付き命令を生成できます。生成コードでは、プリプロセッサの条件付き命令により、実行するコードのセクションがコンパイル時に選択されます。
この例では、Simulink.Variant
オブジェクトを使用して Variant Subsystem ブロックを制御します。バリアントを制御する他の方法の詳細については、Variant Control Modes in Variant Blocksを参照してください。Variant Subsystem ブロック以外のバリアントのタイプに関する詳細については、バリアントとは、およびどのような場合にそれを使用するかを参照してください。
モデルの検査
モデル例 PreprocessorConditionalsUsingVariantSubsystem
を開きます。
model = 'PreprocessorConditionalsUsingVariantSubsystem';
open_system(model);
このモデルには、LeftController
と RightController
という 2 つのバリアント サブシステムが含まれており、それぞれに 2 つの子サブシステム Linear
と Nonlinear
があります。モデルのコールバック関数 PostLoadFcn
で rtwdemo_preprocessor_data.mat
が読み込まれます。コールバック関数を確認するには、Simulink ツールストリップで [モデル化] タブをクリックし、[設定] セクションで [モデル設定]、[モデル プロパティ] をクリックします。[モデル プロパティ] ダイアログ ボックスで [コールバック] タブを開き、[PostLoadFcn] を選択します。あるいは、プログラムでコールバック関数を確認します。
get_param(model,'PostLoadFcn')
ans = 'load preprocessor_data.mat'
コールバック関数により、2 つの Simulink.Variant
オブジェクト LINEAR
および NONLINEAR
と 1 つの Simulink.Parameter
オブジェクト VSSMODE
がインスタンス化されます。LINEAR
バリアントは VSSMODE
が 0
に等しい場合にアクティブになります。NONLINEAR
バリアントは VSSMODE
が 1
の場合にアクティブになります。VSSMODE
は 1
に初期化されています。これらの設定をプログラムで確認します。
LINEAR.Condition
ans = 'VSSMODE==0'
NONLINEAR.Condition
ans = 'VSSMODE==1'
VSSMODE.Value
ans = int32
1
LeftController
および RightController
では、それぞれのサブシステムである Linear
と Nonlinear
のバリアント制御式として LINEAR
と NONLINEAR
を使用しています。この構成を確認するには、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
生成されたコードを表示します。生成されたコードには、いずれのバリアントをコンパイルするかを選択するための LINEAR
と NONLINEAR
を使用した #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