N 次元のテーブル ルックアップを実装する外部 C 関数の統合
レガシ コード ツールを使用して、N 次元のテーブル ルックアップを実装するレガシ C 関数を統合します。
レガシ コード ツールでは以下が可能です。
レガシ関数の仕様を提供する。
シミュレーション中にレガシ コードを呼び出す C-MEX S-Function を生成する。
生成された S-Function をシミュレーション向けにコンパイルし、ビルドする。
モデルの生成コードでレガシ コードを呼び出す方法を指定する TLC ブロック ファイルとオプションの rtwmakecfg.m ファイルを生成する。
レガシ関数の仕様の提供
レガシ コード ツールの関数では、特定のデータ構造体または構造体配列を引数として使用します。このデータ構造体は、最初の入力として 'initialize' を使用する関数 legacy_code() を呼び出すことで初期化できます。構造体の初期化後、統合されるレガシ コードに対応する値に、構造体のプロパティを割り当てます。この例で呼び出されるレガシ関数のプロトタイプは以下のとおりです。
FLT directLookupTableND(const FLT *tableND, const UINT32 nbDims, const UINT32 *tableDims, const UINT32 *tableIdx)
FLT は float に対する typedef で、UINT32 は符号なし int32 に対する typedef です。レガシ ソース コードは、ファイル your_types.h、lookupTable.h および directLookupTableND.c にあります。
defs = []; evalin('base','load rtwdemo_lct_data.mat') % rtwdemo_sfun_dlut3D def = legacy_code('initialize'); def.SFunctionName = 'rtwdemo_sfun_dlut3D'; def.OutputFcnSpec = 'single y1 = DirectLookupTable3D(single p1[][][], uint32 p2[3], uint32 u1[3])'; def.HeaderFiles = {'lookupTable.h'}; def.SourceFiles = {'directLookupTableND.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def]; % rtwdemo_sfun_dlut4D def = legacy_code('initialize'); def.SFunctionName = 'rtwdemo_sfun_dlut4D'; def.OutputFcnSpec = 'single y1 = DirectLookupTable4D(single p1[][][][], uint32 p2[4], uint32 u1[4])'; def.HeaderFiles = {'lookupTable.h'}; def.SourceFiles = {'directLookupTableND.c'}; def.IncPaths = {'rtwdemo_lct_src'}; def.SrcPaths = {'rtwdemo_lct_src'}; defs = [defs; def];
シミュレーション用の S-Function の生成
入力引数 'defs' によって示される説明に従って C-MEX S-Function を生成するために、関数 legacy_code() を再び呼び出します。最初の入力は 'sfcn_cmex_generate' に設定します。この S-Function により、シミュレーション中にレガシ関数が呼び出されます。S-Function のソース コードは、ファイル rtwdemo_sfun_dlut3D.c と rtwdemo_sfun_dlut4D.c にあります。
legacy_code('sfcn_cmex_generate', defs);
生成された S-Function のシミュレーション向けのコンパイル
C-MEX S-Function ソース ファイルの生成後、Simulink® を使用したシミュレーション用に S-Function をコンパイルするために、関数 legacy_code() を再び呼び出します。最初の入力は 'compile' に設定します。
legacy_code('compile', defs);
### Start Compiling rtwdemo_sfun_dlut3D mex('-I/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc23a_2181783_2675014/tp23db1089/simulinkcoder-ex19426386', '-c', '-outdir', '/tmp/Bdoc23a_2181783_2675014/tpabb6eb8f_a4b2_4ca1_ab89_e5ba688b5ad0', '/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/directLookupTableND.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_dlut3D.c', '-I/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc23a_2181783_2675014/tp23db1089/simulinkcoder-ex19426386', '/tmp/Bdoc23a_2181783_2675014/tpabb6eb8f_a4b2_4ca1_ab89_e5ba688b5ad0/directLookupTableND.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_dlut3D ### Exit ### Start Compiling rtwdemo_sfun_dlut4D mex('-I/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc23a_2181783_2675014/tp23db1089/simulinkcoder-ex19426386', '-c', '-outdir', '/tmp/Bdoc23a_2181783_2675014/tp5eb18f08_81e2_4e1f_953b_35c0492caf5a', '/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src/directLookupTableND.c') Building with 'gcc'. MEX completed successfully. mex('rtwdemo_sfun_dlut4D.c', '-I/mathworks/devel/bat/Bdoc23a/build/matlab/toolbox/rtw/rtwdemos/rtwdemo_lct_src', '-I/tmp/Bdoc23a_2181783_2675014/tp23db1089/simulinkcoder-ex19426386', '/tmp/Bdoc23a_2181783_2675014/tp5eb18f08_81e2_4e1f_953b_35c0492caf5a/directLookupTableND.o') Building with 'gcc'. MEX completed successfully. ### Finish Compiling rtwdemo_sfun_dlut4D ### Exit
コード生成用の TLC ブロック ファイルの生成
S-Function をコンパイルしてシミュレーションで使用した後、関数 legacy_code() を再び呼び出すことができます。最初の入力を 'sfcn_tlc_generate' に設定して、TLC ブロック ファイルを生成します。このブロック ファイルで、モデルの生成コードでレガシ コードを呼び出す方法を指定します。TLC ブロック ファイルを生成せずに、S-Function を含むモデルのコードを生成しようとすると、コード生成に失敗します。S-Function の TLC ブロック ファイルは、rtwdemo_sfun_dlut3D.tlc および rtwdemo_sfun_dlut4D.tlc です。
legacy_code('sfcn_tlc_generate', defs);
コード生成用の rtwmakecfg.m ファイルの生成
TLC ブロック ファイルを作成した後、関数 legacy_code() を再び呼び出すことができます。最初の入力を 'rtwmakecfg_generate' に設定して、コード生成をサポートする rtwmakecfg.m ファイルを生成します。S-Function に必要なソース ファイルとヘッダー ファイルが S-Function と同じフォルダーになく、コード生成時に作成される makefile 内にこれらの依存関係を追加する場合は、この rtwmakecfg.m ファイルを生成してください。
legacy_code('rtwmakecfg_generate', defs);
生成された S-Function を呼び出すためのマスクされた S-Function ブロックの生成
C-MEX S-Function ソースのコンパイルが終了したら、関数 legacy_code() を再び呼び出すことができます。最初の入力を 'slblock_generate' に設定して、その S-Function を呼び出すマスク済みの S-Function ブロックを生成します。このブロックはソフトウェアによって新しいモデルに配置されます。そのブロックを既存のモデルにコピーできます。
legacy_code('slblock_generate', defs);
レガシ コードとの統合の表示
モデル rtwdemo_lct_lut は、レガシ コードとのモデルの統合を示しています。サブシステム TestFixpt は、レガシ C 関数の呼び出しに利用できます。Display ブロックは、関数の出力と組み込み Simulink® Lookup ブロックの出力を比較します。その結果は同じになります。
open_system('rtwdemo_lct_lut') open_system('rtwdemo_lct_lut/TestLut1') sim('rtwdemo_lct_lut')