S-Function のインライン化
生成コードに含める S-Function を記述するときは、シミュレーションのみに使用する S-Function を記述するときよりも要件が多くなります。S-Function のインライン化を進める前に、想定する要件と機能を満たしていることを確認してください。詳細については、S-Function とコード生成を参照してください。S-Function がマルチレートの場合は、時間ベースのスケジューリングとコード生成、マルチタスク実行のモデル化、およびRate Grouping Compliance and Compatibility Issuesを参照してください。
ブロック ターゲット ファイルを使用した S-Function のインライン化
S-Function をインライン化する状況
C MEX S-Function の場合、ビルド フェーズの開始時点でソース コード (.c
ファイル) が使用可能であれば、ERT 以外のターゲットで元の C MEX コードの呼び出しがサポートされます。Fortran または MATLAB® 言語の S-Function の場合は、それらを含む Simulink® モデルの完全なコード生成のためにインライン化が必要になります。さらに、S-Function をインライン化することにした場合は、完全にインライン化するかラップするかを決めなければなりません。
完全インライン化 S-Function
完全インライン化 S-Function のブロック ターゲット ファイルは、ブロックの機能を生成コードのさまざまな部分 (開始コード、出力コードなど) に直接インライン化する方法を定義する自己完結型のファイルです。このアプローチは、比較的小さいアルゴリズムで多数のモードやデータ型をサポートする場合や、コード サイズがそれほど大きくない場合に最も便利です。
関数ベースまたはラップ型のコード生成
ブロックのコードの物理的なサイズが大きすぎてインライン化に適さない場合は、入力、出力、およびパラメーターを収集し、記述した関数を呼び出してブロックの機能を実行するようにブロック ターゲット ファイルを記述します。これは、関数のコードが大きい場合や、このブロックのインスタンスがモデル内に多数ある場合に、生成コードのサイズの点で利点があります。もちろん、ブロック アルゴリズムを完全にインライン化するか関数呼び出しを生成するかを検討するときは、関数呼び出しのオーバーヘッドを考慮しなければなりません。
関数ベースのコード生成を選択した場合は、さらに 2 つのオプションについて検討が必要です。
関数を 1 回記述して
.c
ファイルに含め、TLC コードのBlockTypeSetup
メソッドでサポート関数への外部参照を指定する。サポート関数を含むモジュールの名前にはLibAddToModelSources
を使用します。このアプローチでは、通常、使用する関数をファイルごとに 1 つにして実行可能ファイルをできるだけ小さくします。より高度な TLC ファイルを記述する。
Start
やOutputs
などのメソッドに加え、それぞれのコード生成バッファーでカスタマイズ バージョンの関数 (データ型、幅、アルゴリズムなど) を条件付きで生成し、別々の.c
ファイルに書き込みます。ファイルには、使用可能なすべての関数ではなく、このモデルで使用される関数だけを含める必要があります。
いずれのアプローチでも最適なコードを生成できます。1 つ目のオプションでは、S-Function でサポートされるデータ型、信号の幅、アルゴリズムの選択肢が多いと、ファイル数が数百になることがあります。2 つ目のアプローチでは、記述するのは難しくなりますが、より管理しやすいコード生成ライブラリになり、1 つ目のアプローチとまったく同じように厳密なコードを記述できます。
ラップの詳細については、ラッパー インライン化 S-Function の例を参照してください。
MATLAB ファイル S-Function のインライン化
MATLAB ファイル S-Function の機能を生成コードでインライン化できます。MATLAB ファイル S-Function のブロック ターゲット ファイルを記述するプロセスは、C MEX S-Function を記述するプロセスと本質的に同じです。
メモ
MATLAB ファイル S-Function を完全にインライン化するとパフォーマンスを改善できますが、Simulink Accelerator™ またはコード ジェネレーターには MATLAB Math Library の C または C++ API は含まれていません。そのため、MATLAB Math Library の関数は TLC ファイルからは呼び出せません。
次の例では、コード生成に使用する C MEX S-Function と MATLAB ファイル S-Function が等価であることを示します。S-Function MATLAB ファイル timestwo.m
は C MEX S-Function timestwo
と等価です。C MEX S-Function timestwo
の TLC ファイルは、S-Function MATLAB ファイル timestwo.m
に対して機能します。TLC に必要なのは S-Function のルート名だけで、タイプは必要ないため、TLC は S-Function のタイプには依存しません。timestwo
の場合、コード ジェネレーターで TLC ファイルを実装する方法が次の 1 行で指定されています。
%implements "timestwo" "C"
これを実際に試してみます。
次のようなサンプル モデルを作成します。
ファイル
timestwo.m
をフォルダー
(開く) から一時フォルダーにコピーします。matlabroot
/toolbox/simulink/simdemos/simfeaturesファイル
timestwo.tlc
をフォルダー
(開く) から同じ一時フォルダーにコピーします。matlabroot
/toolbox/simulink/simdemos/simfeatures/tlc_cMATLAB で、フォルダーを一時フォルダーに切り替え (
cd
)、timestwo.
を呼び出す S-Function ブロックを含む Simulink モデルを作成します。Inport ブロックのパラメーター ダイアログ ボックスの [信号属性] タブで、[端子の次元] パラメーターを
5
に設定します。
Simulink では、MATLAB ファイル S-Function がシミュレーションに使用されます。これは、MATLAB 検索パスで、matlabpath
にある C MEX S-Function timestwo
よりも現在のフォルダーにある timestwo.m
が先に見つかるためです。次の MATLAB コマンドを入力して、コード ジェネレーターで使用される S-Function を確認します。
which timestwo
応答は、一時フォルダーにある MATLAB ファイル S-Function timestwo.m
になります。
生成コードでは、timestwo.tlc
ファイルで MATLAB ファイル S-Function がインライン化されます。
/* S-Function (timestwo): '<Root>/MATLAB S-Function' */ /* Multiply input by two */ { int_T i1; const real_T *u0 = ×2_B.Gain[0]; real_T *y0 = ×2_Y.Out1[0]; for (i1=0; i1 < 5; i1++) { y0[i1] = u0[i1] * 2.0; } }
出力は各入力 u0[i1]
と 2.0 の積です。コード ジェネレーターは、ブロック ターゲット ファイルから次の Outputs
メソッドを使用してコードを生成します。
%function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% /* Multiply input by two */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * 2.0; %endroll %endfunction
これらの MATLAB ファイル S-Function と TLC ファイルの一時コピーを変更して、それらの連携を確認します。最初は TLC ファイルのコメントだけを変更して、生成コードに変更が反映されることを確認します。その後、アルゴリズムの変更も試してみます。
C MEX S-Function のインライン化の詳細については、Inline C MEX S-Functionsを参照してください。
Fortran (F-MEX) S-Function のインライン化
Fortran MEX S-Function の機能は、TLC ブロック ターゲット ファイルを使用して完全にインライン化できます。このインターフェイスは、関数 timestwo
を実装する Fortran MEX S-Function で示すことができます。Fortran S-Function のサンプル コードを次に示します。
C C FTIMESTWO.FOR C C C A sample FORTRAN representation of a C timestwo S-function. C Copyright 1990-2000 The MathWorks, Inc. C C===================================================== C Function: SIZES C C Abstract: C Set the size vector. C C SIZES returns a vector which determines model C characteristics. This vector contains the C sizes of the state vector and other C parameters. More precisely, C SIZE(1) number of continuous states C SIZE(2) number of discrete states C SIZE(3) number of outputs C SIZE(4) number of inputs C SIZE(5) number of discontinuous roots in C the system C SIZE(6) set to 1 if the system has direct C feedthrough of its inputs, C otherwise 0 C C===================================================== SUBROUTINE SIZES(SIZE) C .. Array arguments .. INTEGER*4 SIZE(*) C .. Parameters .. INTEGER*4 NSIZES PARAMETER (NSIZES=6) SIZE(1) = 0 SIZE(2) = 0 SIZE(3) = 1 SIZE(4) = 1 SIZE(5) = 0 SIZE(6) = 1 RETURN END C C===================================================== C Function: OUTPUT C C Abstract: C Perform output calculations for continuous C signals. C===================================================== C .. Parameters .. SUBROUTINE OUTPUT(T, X, U, Y) REAL*8 T REAL*8 X(*), U(*), Y(*) Y(1) = U(1) * 2.0 RETURN END C C===================================================== C Stubs for unused functions. C===================================================== SUBROUTINE INITCOND(X0) REAL*8 X0(*) C --- Nothing to do. RETURN END SUBROUTINE DERIVS(T, X, U, DX) REAL*8 T, X(*), U(*), DX(*) C --- Nothing to do. RETURN END SUBROUTINE DSTATES(T, X, U, XNEW) REAL*8 T, X(*), U(*), XNEW(*) C --- Nothing to do. RETURN END SUBROUTINE DOUTPUT(T, X, U, Y) REAL*8 T, X(*), U(*), Y(*) C --- Nothing to do. RETURN END SUBROUTINE TSAMPL(T, X, U, TS, OFFSET) REAL*8 T,TS,OFFSET,X(*),U(*) C --- Nothing to do. RETURN END SUBROUTINE SINGUL(T, X, U, SING) REAL*8 T, X(*), U(*), SING(*) C --- Nothing to do. RETURN END
上記のコードを任意の作業フォルダーのファイル ftimestwo.for
にコピーします。
これを簡単なモデルの S-Function ブロックに含めると、S-Function をインライン化するインターフェイスを示すことができます。Fortran MEX 環境を設定したら、作業フォルダーの S-Function をフォルダー
(開く) のファイル matlabroot
/simulink/srcsimulink.for
と共にコンパイルし、使用するコードを準備します。Fortran MEX 環境の設定の詳細については、Create Level-2 Fortran S-Functionsを参照してください。
MATLAB コマンド ラインで mex
コマンドを使用してコードをコンパイルします。
mex ftimestwo.for simulink.for
次に、このブロックを固定ステップ ソルバーと grt
ターゲットを設定した簡単なモデルから参照します。
このブロックをインライン化する TLC コードは、timestwo.tlc
に変更を加えた形式になります。作業フォルダーに ftimestwo.tlc
という名前のファイルを作成し、このコードを含めます。
%implements "ftimestwo" "C" %function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% /* Multiply input by two */ %assign rollVars = ["U", "Y"] %roll idx = RollRegions, lcv = RollThreshold, block, ... "Roller", rollVars %<LibBlockOutputSignal(0, "", lcv, idx)> = \ %<LibBlockInputSignal(0, "", lcv, idx)> * 2.0; %endroll %endfunction
これで、ftimestwo
Fortran MEX S-Function のコードを生成できます。結果のコードの ftimestwo
に固有のフラグメントは次のとおりです。
/* S-Function Block: <Root>/F-MEX S-Function */ /* Multiply input by two */ rtB.F_MEX_S_Function = rtB.Gain * 2.0;