ブロック ターゲット ファイルのメソッド
ブロック関数の概要
各ブロックに、そのブロックのコードをどのように生成するかを決めるターゲット ファイルがあります。ブロックの正確なパラメーターや接続のタイプ (幅のある入力かスカラー入力かなど) に応じて、コードはさまざまに異なります。
各ブロック ターゲット ファイル内で、"ブロック関数" により、モデルまたはサブシステムの start
、output
、update
などの関数で出力するブロックのコードを指定します。
各ブロック ターゲット ファイル内で宣言された関数は、システム ターゲット ファイルによって呼び出されます。以下の表で、block
は Simulink® ブロックの名前 (Gain ブロックは gain
など) を表し、system
はブロックが含まれているサブシステムを表しています。最初の表にリストされた 2 つは、前処理とセットアップに使用する関数です。これらの関数は、いずれも生成コードを出力しません。
以下の関数は、コード ジェネレーターで適宜配置される実行可能コードを生成します。
オブジェクト指向プログラミングの観点では、各ブロック ターゲット ファイルに同じ関数が含まれるため、これらの関数は実質的にポリモーフィックです。どのブロック関数を実行するかは、実行時にブロックのタイプに応じて Target Language Compiler で動的に決定されます。つまり、システム ファイルでは、たとえば関数 Outputs
を実行することだけを指定します。個別の関数 Outputs
は、ブロックのタイプに応じて Target Language Compiler で決定されます。
ブロック ターゲット ファイルを記述するには、これらのポリモーフィックなブロック関数を Target Language Compiler ライブラリ関数と組み合わせて使用します。Target Language Compiler ライブラリ関数の完全な一覧については、Target Language Compilerの「TLC 関数ライブラリ リファレンス」を参照してください。
BlockInstanceSetup(block, system)
関数 BlockInstanceSetup
は、この関数がモデル内のターゲット ファイルで定義されているブロックに対して実行されます。たとえば、モデルに 10 個の From Workspace ブロックが含まれている場合、From Workspace ブロックの各インスタンスに対して 1 回ずつ、fromwks.tlc
の関数 BlockInstanceSetup
が 10 回実行されます。BlockInstanceSetup
は、特定のブロック タイプの各インスタンスに対してコードを生成する場合に使用します。
このブロック関数の内部から呼び出して使用可能なユーティリティ処理関数については、Target Language Compilerの「TLC 関数ライブラリ リファレンス」を参照してください。関数 BlockInstanceSetup
の例については、ファイル
を参照してください。matlabroot
/rtw/c/tlc/blocks/lookup2d.tlc
構文
BlockInstanceSetup(block, system) void block = Reference to a Simulink block system = Reference to a nonvirtual Simulink subsystem
次の例では BlockInstanceSetup
を使用しています。
%function BlockInstanceSetup(block, system) void %if (block.InMask == "yes") %assign blockName = LibParentMaskBlockName(block) %else %assign blockName = LibGetFormattedBlockPath(block) %endif %if (CodeFormat == "Embedded-C") %if !(ParamSettings.ColZeroTechnique == "NormalInterp" && ... ParamSettings.RowZeroTechnique == "NormalInterp") %selectfile STDOUT Note: Removing repeated zero values from the X and Y axes will produce more efficient code for block: %<blockName>. To locate this block, type open_system('%<blockName>') at the MATLAB command prompt. %selectfile NULL_FILE %endif %endif %endfunction
BlockTypeSetup(block, system)
BlockTypeSetup
は、コード生成の開始前にブロック タイプごとに 1 回実行されます。つまり、モデルに 10 個の Lookup Table ブロックが存在する場合、look_up.tlc
の関数 BlockTypeSetup
は 1 回だけ呼び出されます。この関数は、特定のタイプの複数のブロックに対して一般的な作業を行う場合に使用します。
このブロック関数の内部から呼び出す、該当する関数の一覧については、Target Language Compilerの「TLC 関数ライブラリ リファレンス」を参照してください。関数 BlockTypeSetup
の例については、look_up.tlc
を参照してください。
構文
BlockTypeSetup(block, system) void block = Reference to a Simulink block system = Reference to a nonvirtual Simulink subsystem
たとえば、S-Function foo
でヘッダー ファイルに #define
と 2 つの関数宣言が必要な場合、次のように定義できます。
%function BlockTypeSetup(block, system) void %% Place a #define in the model's header file %openfile buffer #define A2D_CHANNEL 0 %closefile buffer %<LibCacheDefine(buffer)> %% Place function prototypes in the model's header file %openfile buffer void start_a2d(void); void reset_a2d(void); %closefile buffer %<LibCacheFunctionPrototype(buffer)> %endfunction
残りのブロック関数は、モデル内の各ブロックに対して 1 回ずつ実行されます。
Enable(block, system)
コード ジェネレーターでは、関数 Enable
を含むブロックが Simulink サブシステムにある場合、非バーチャル サブシステムの関数 Enable
を常に作成します。ブロックのターゲット ファイルに関数 Enable
を含めると、このサブシステムの関数 Enable
にブロック固有の有効化コードが配置されます。次に例を示します。
%% Function: Enable ============================================ %% Abstract: %% Subsystem Enable code is required only for the discrete form %% of the Sine Block. Setting the Boolean to TRUE causes the %% Output function to resync its last values of cos(wt) and %% sin(wt). %% %function Enable(block, system) Output %if LibIsDiscrete(TID) /* %<Type> Block: %<Name> */ %<LibBlockIWork(SystemEnable, "", "", 0)> = (int_T) TRUE; %endif %endfunction
Disable(block, system)
関数 Disable
を含むブロックが Simulink サブシステムにある場合、非バーチャル サブシステムの関数 Disable
が常に作成されます。ブロックのターゲット ファイルに関数 Disable
を含めると、このサブシステムの関数 Disable
にブロック固有の無効化コードが配置されます。
Start(block, system)
関数 Start
にコードを配置するには、関数 Start
を含めます。関数 Start
の内部のコードは 1 回だけ実行されます。一般に、関数 Start
は、シミュレーションの開始時にコードを 1 回実行する場合 (作業ベクトルの値を初期化する場合など) や、そのコードが含まれているサブシステムが有効になったときに再実行する必要がないコードを実行する場合に含めます。関数 Start
の例については、constant.tlc
を参照してください。
%% Function: Start ============================================ %% Abstract: %% Set the output to the constant parameter value if the block %% output is visible in the model's start function scope, i.e., %% it is in the global rtB structure. %% %function Start(block, system) Output %if LibBlockOutputSignalIsInBlockIO(0) /* %<Type> Block: %<Name> */ %assign rollVars = ["Y", "P"] %roll idx = RollRegions, lcv = RollThreshold, block, ... "Roller", rollVars %assign yr = LibBlockOutputSignal(0,"", lcv, ... "%<tRealPart>%<idx>") %assign pr = LibBlockParameter(Value, "", lcv, ... "%<tRealPart>%<idx>") %<yr> = %<pr>; %if LibBlockOutputSignalIsComplex(0) %assign yi = LibBlockOutputSignal(0, "", lcv, ... "%<tImagPart>%<idx>") %assign pi = LibBlockParameter(Value, "", lcv, ... "%<tImagPart>%<idx>") %<yi> = %<pi>; %endif %endroll %endif %endfunction %% Start
InitializeConditions(block, system)
ブロックの関数 InitializeConditions
から生成される TLC コードは、2 つのうちのどちらかの場所に配置されます。有効になったときに状態をリセットするように構成されている場合、非バーチャル サブシステムに関数 Initialize
が含まれています。この場合、このブロック関数によって生成される TLC コードはサブシステムの関数 Initialize
に配置され、このサブシステムの関数 Initialize
が関数 start
によって呼び出されます。一方、Simulink ブロックがルート システム内または関数 Initialize
を必要としない非バーチャル サブシステム内にある場合、このブロック関数から生成されるコードは関数 start
に直接配置 (インライン化) されます。
ブロック関数の Start
と InitializeConditions
には微妙な違いがあります。一般に、そのコードが含まれているサブシステムが有効化されたときに再実行する必要がないコードを実行する場合は関数 Start
を含めます。そのコードが含まれているサブシステムが有効化されたときに再実行する必要があるコードを実行する場合は関数 InitializeConditions
を含めます。次に例を示します。
%% Function: InitializeConditions ============================= %% %% Abstract: Invalidate the stored output and input in %% rwork[1 2*blockWidth] by setting the time stamp stored %% in rwork[0]) to rtInf. %% %function InitializeConditions(block, system) Output /* %<Type> Block: %<Name> */ %<LibBlockRWork(PrevT, "", "", 0)> = %<LibRealNonFinite(inf)>; %endfunction
メモ
関数 InitializeConditions
を解析するには、S-Function に少なくとも 1 つの連続状態または離散状態が登録されている必要があります。
Outputs(block, system)
一般に、ブロックには関数 Outputs
を含めます。ブロックの関数 Outputs
によって生成される TLC コードは、2 つのうちのどちらかの場所に配置されます。コードは、ブロックが非バーチャル サブシステム内にない場合はモデルの関数 Outputs
に直接配置され、ブロックが非バーチャル サブシステム内にある場合はサブシステムの関数 Outputs
に配置されます。次に例を示します。
%% Function: Outputs ========================================== %% Abstract: %% Y[i] = fabs(U[i]) if U[i] is real or %% Y[i] = sqrt(U[i].re^2 + U[i].im^2) if U[i] is complex. %% %function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% %assign inputIsComplex = LibBlockInputSignalIsComplex(0) %assign RT_SQUARE = "RT_SQUARE" %% %assign rollVars = ["U", "Y"] %if inputIsComplex %roll sigIdx = RollRegions, lcv = RollThreshold, ... block, "Roller", rollVars %% %assign ur = LibBlockInputSignal( 0, "", lcv, ... "%<tRealPart>%<sigIdx>") %assign ui = LibBlockInputSignal( 0, "", lcv, ... "%<tImagPart>%<sigIdx>") %% %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx) %<y> = sqrt( %<RT_SQUARE>( %<ur> ) + %<RT_SQUARE>( %<ui> ) ); %endroll %else %roll sigIdx = RollRegions, lcv = RollThreshold, ... block, "Roller", rollVars %assign u = LibBlockInputSignal (0, "", lcv, sigIdx) %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx) %<y> = fabs(%<u>); %endroll %endif %endfunction
メモ
ゼロクロッシング リセット コードは関数 Outputs
に配置されます。
S-Function からインライン化コードを生成するための TLC コードを記述する場合に TLC コードに関数 Outputs
が含まれている場合、次のすべての条件に該当する場合は TLC コードの変更が必要になります。
出力端子が定数のサンプル時間を使用または継承している。出力端子の値が定数である。
S-Function がマルチレート S-Function であるか、端子ベースのサンプル時間を使用している。
この場合、関数 Outputs
の代わりに関数 OutputsForTID
を使用して、TLC コードで定数値の出力端子に対するコードを生成しなければなりません。詳細については、Specifying Constant Sample Time (Inf) for a Portを参照してください。
Update(block, system)
ブロックのコードを各メジャー タイム ステップで更新する必要がある場合は、関数 Update
を含めます。この関数から生成されるコードは、ブロックが非バーチャル サブシステム内にあるかどうかに応じて、モデルまたはサブシステムのいずれかの関数 Update
に配置されます。次に例を示します。
%% Function: Update ============================================ %% Abstract: %% X[i] = U[i] %% %function Update(block, system) Output /* %<Type> Block: %<Name> */ %assign rollVars = ["U", "Xd"] %roll idx = RollRegions, lcv = RollThreshold, block, ... "Roller", rollVars %assign u = LibBlockInputSignal(0, "", lcv, idx) %assign x = LibBlockDiscreteState("", lcv, idx) %<x> = %<u>; %endroll %endfunction %% Update
Derivatives(block, system)
ブロックの連続状態を計算するためのコードを生成する場合は、関数 Derivatives
を含めます。この関数から生成されるコードは、ブロックが非バーチャル サブシステム内にあるかどうかに応じて、モデルまたはサブシステムのいずれかの関数 Derivatives
に配置されます。
Terminate(block, system)
MdlTerminate
にコードを配置するには、関数 Terminate
を含めます。この関数をユーザー定義の S-Function のターゲット ファイルで使用して、データの保存、メモリの解放、ターゲットのハードウェアのリセットなどを実行できます。関数 Terminate
の例については、tofile.tlc
を参照してください。