Main Content

ブロック ターゲット ファイルのメソッド

ブロック関数の概要

各ブロックに、そのブロックのコードをどのように生成するかを決めるターゲット ファイルがあります。ブロックの正確なパラメーターや接続のタイプ (幅のある入力かスカラー入力かなど) に応じて、コードはさまざまに異なります。

各ブロック ターゲット ファイル内で、"ブロック関数" により、モデルまたはサブシステムの startoutputupdate などの関数で出力するブロックのコードを指定します。

各ブロック ターゲット ファイル内で宣言された関数は、システム ターゲット ファイルによって呼び出されます。以下の表で、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 に直接配置 (インライン化) されます。

ブロック関数の StartInitializeConditions には微妙な違いがあります。一般に、そのコードが含まれているサブシステムが有効化されたときに再実行する必要がないコードを実行する場合は関数 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 を参照してください。

関連するトピック