Main Content

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

生成コード内の変数の保持

モデルの反復的な開発においては、モデル実行で生成される信号や状態の値を取得します。実行時にはパラメーターの値の調整も行い、信号および状態の結果を確認します。そうすることで、設計を決定する際の判断をこのような出力の解析に基づいたものにできます。ラピッド プロトタイピング環境では、信号、状態、パラメーターのデータにアクセスするために、データをアドレス可能なメモリに格納するように生成コードを設定できます。

使用するシステム ターゲット ファイルに応じて (grt.tlc など)、既定では、最適化設定により、次を行うことで生成されたコードを効率化できます。

  • 信号および一部の状態向けの不要なグローバル ストレージとローカル ストレージを削除します。

    ただし、最適化によってシステムの基本入力と出力を表すルートレベルの Inport ブロックと Outport ブロックのストレージは削除されません。このデータにアクセスするために、最適化を検討する必要はありません。

  • ブロック パラメーターの数値をインライン化します。コードではパラメーターはメモリに格納されないため、コードの実行中にパラメーターと対話できません。

その代わりに、このデータ用にアドレス可能なメモリを割り当てるコードを生成するには、最適化を無効にするか、個々のデータ項目に対してコード生成設定を指定して最適化をオーバーライドします。

信号、状態、パラメーター データへの実行時のアクセス

モデルの反復的な開発においては、モデル実行で生成される出力信号や状態のデータを取得します。実行時にはパラメーターの値の調整も行い、出力での結果を確認します。そうすることで、設計を決定する際の判断をこのような出力の解析に基づいたものにできます。ラピッド プロトタイピング環境では、この信号、状態、パラメーターのデータにアクセスするために、データをアドレス可能なメモリに格納するように生成コードを設定できます。

既定では、生成コードの効率を高めるために、最適化設定によって、不要な信号ストレージを削除したり、ブロック パラメーターの数値をインライン化したりするように設定されています。その代わりに、このデータ用にアドレス可能なメモリを割り当てるコードを生成するには、最適化を無効にするか、個々のデータ項目に対してコード生成設定を指定します。

モデル例の確認

この例のためにモデル rtwdemo_basicsc を準備するスクリプトを実行します。

run(fullfile(matlabroot,'examples','simulinkcoder','main','prepare_rtwdemo_basicsc'));

以下のデータはコード生成のために構成されます。

  • パラメーター UPPERLOWERLIMITK1、および K2 (Stateflow)、T1BreakT1DataT2BreakT2 Data

  • 信号 Input1Input2Input3Input4、および output

  • 状態 X (遅延) および mode (データ ストア メモリ書き込みおよび Stateflow)

モデル例 rtwdemo_basicsc を開きます。

rtwdemo_basicsc

このモデルでは MATLAB の数値変数をベース ワークスペースに読み込みます。ワークスペース変数は、モデルにいくつかのブロック パラメーターを設定します。しかし、モデル内の Gain ブロックは、リテラル値 2 を使用します。

最適化の無効化

1. モデルで、モデル コンフィギュレーション パラメーターの [信号ストレージの再利用] をクリアします。この最適化のほか、[余分なローカル変数の削除 (式の畳み込み)] などの最適化をクリアすると、生成コードで信号線にメモリが割り当てられます。[信号ストレージの再利用] をクリアすると、他のほとんどの最適化が無効になります。

set_param('rtwdemo_basicsc','OptimizeBlockIOStorage','off')

2.モデル コンフィギュレーション パラメーター [既定のパラメーター動作] を [Tunable] に設定します。このコンフィギュレーション パラメーターを [Tunable] に設定すると、生成コードでブロック パラメーターおよびワークスペース変数にメモリが割り当てられます。

set_param('rtwdemo_basicsc','DefaultParameterBehavior','Tunable')

3.コードを生成します。

rtwbuild('rtwdemo_basicsc')
### Starting build procedure for: rtwdemo_basicsc
### Successful completion of build procedure for: rtwdemo_basicsc

4.コード生成レポートで、ファイル rtwdemo_basicsc.h を表示します。このヘッダー ファイルは、信号のデータを格納する構造体型を定義しています。構造体にはモデル内の各信号線を表すフィールドが格納されます。たとえば、Gain という名前の Gain ブロックの出力信号はフィールド Gain として表されています。

file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T;',1,1)
/* Block signals (default storage) */
typedef struct {
  real32_T Table1;                     /* '<Root>/Table1' */
  real32_T Gain;                       /* '<Root>/Gain' */
  real32_T Delay;                      /* '<Root>/Delay' */
  real32_T Table2;                     /* '<Root>/Table2' */
  boolean_T RelOp1;                    /* '<Root>/RelOp1' */
  boolean_T RelOp2;                    /* '<Root>/RelOp2' */
  boolean_T LogOp;                     /* '<Root>/LogOp' */
} B_rtwdemo_basicsc_T;

このファイルは、ブロック パラメーターのデータを格納する構造体型を定義しています。たとえば、Gain ブロックの [ゲイン] パラメーターはフィールド Gain_Gain として表されています。構造体のその他のフィールドは、信号および状態の初期条件など、モデルの他のブロック パラメーターやワークスペース変数を表します。

rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
/* Parameters (default storage) */
struct P_rtwdemo_basicsc_T_ {
  real_T K2;                           /* Variable: K2
                                        * Referenced by: '<Root>/Stateflow Chart'
                                        */
  real32_T LOWER;                      /* Variable: LOWER
                                        * Referenced by: '<Root>/Constant2'
                                        */
  real32_T T1Break[11];                /* Variable: T1Break
                                        * Referenced by: '<Root>/Table1'
                                        */
  real32_T T1Data[11];                 /* Variable: T1Data
                                        * Referenced by: '<Root>/Table1'
                                        */
  real32_T T2Break[3];                 /* Variable: T2Break
                                        * Referenced by: '<Root>/Table2'
                                        */
  real32_T T2Data[9];                  /* Variable: T2Data
                                        * Referenced by: '<Root>/Table2'
                                        */
  real32_T UPPER;                      /* Variable: UPPER
                                        * Referenced by: '<Root>/Constant1'
                                        */
  real32_T Gain_Gain;                  /* Computed Parameter: Gain_Gain
                                        * Referenced by: '<Root>/Gain'
                                        */
  real32_T Delay_InitialCondition; /* Computed Parameter: Delay_InitialCondition
                                    * Referenced by: '<Root>/Delay'
                                    */
  uint32_T Table2_maxIndex[2];         /* Computed Parameter: Table2_maxIndex
                                        * Referenced by: '<Root>/Table2'
                                        */
  boolean_T DataStoreMemory_InitialValue;
                             /* Computed Parameter: DataStoreMemory_InitialValue
                              * Referenced by: '<Root>/Data Store Memory'
                              */
};

5.ファイル rtwdemo_basicsc_data.c を表示します。このソース ファイルは、パラメーター構造体にグローバル メモリを割り当て、モデルのパラメーターの値に基づいてフィールドの値を初期化します。

6.ソース ファイル rtwdemo_basicsc.c を表示します。このコードは、信号のデータを格納する構造体変数にグローバル メモリを割り当てます。

file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.c');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T rtwdemo_basicsc_B;',1,1)
/* Block signals (default storage) */
B_rtwdemo_basicsc_T rtwdemo_basicsc_B;

信号の値は、モデルの関数 step のコード アルゴリズムで計算されます。その後、それらの値が信号構造体のフィールドに代入されます。アルゴリズムによる計算には、パラメーター構造体のフィールドのパラメーター値が使用されます。

最適化からのデータ項目の除外

[信号ストレージの再利用] などのコード生成の最適化を選択する際、個々のデータ項目について、最適化しないで保持することができます。それらの項目に対しては、生成コードでアドレス可能メモリが割り当てられます。

前にクリアした最適化を選択します。

set_param('rtwdemo_basicsc','OptimizeBlockIOStorage','on')
set_param('rtwdemo_basicsc','LocalBlockOutputs','on')
set_param('rtwdemo_basicsc','DefaultParameterBehavior','Inlined')

1. [モデル化] タブで [モデル データ エディター] をクリックします。

2.モデル データ エディターで、[信号] タブを検査します。

3.[ビューの変更] ドロップダウン リストを Instrumentation に設定します。

4.モデルで、Gain ブロックの出力信号を選択します。

5.モデル データ エディターで、[Test Point] 列のチェック ボックスをオンにします。

portHandle = get_param('rtwdemo_basicsc/Gain','PortHandles');
portHandle = portHandle.Outport;
set_param(portHandle,'TestPoint','on')

6.[パラメーター] タブを検査します。

7.モデルで Gain ブロックを選択します。

8.モデル データ エディターで、[値] 列を使用してゲイン値を K1 に設定します。

10. K1 の横にあるアクション ボタン (3 つの縦向きのドット) をクリックし、[作成] を選択します。

11.[新規データの作成] ダイアログ ボックスで、[値]Simulink.Parameter(2) に設定して [作成] をクリックします。K1 という名前で、値が 2Simulink.Parameter オブジェクトがベース ワークスペースに表示されます。

12.K1 のプロパティ ダイアログ ボックスで、[ストレージ クラス] を使用して Auto 以外のストレージ クラスを適用します。たとえば、パラメーター オブジェクトをグローバル パラメーター構造体のフィールドとして表すには、ストレージ クラス Model default を使用します。

set_param('rtwdemo_basicsc/Gain','Gain','K1');
K1 = Simulink.Parameter(2);
K1.StorageClass = 'Model default';

13. コードを生成します。

rtwbuild('rtwdemo_basicsc')
### Starting build procedure for: rtwdemo_basicsc
### Successful completion of build procedure for: rtwdemo_basicsc

14. コード生成レポートで、ファイル rtwdemo_basicsc.h を表示します。信号のデータを格納する構造体は、Gain ブロックのテスト ポイント出力を表すフィールド Gain のみを 1 つ定義しています。

file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.h');
rtwdemodbtype(file,'/* Block signals (default storage) */',...
    'B_rtwdemo_basicsc_T;',1,1)
/* Block signals (default storage) */
typedef struct {
  real32_T Gain;                       /* '<Root>/Gain' */
} B_rtwdemo_basicsc_T;

ブロック パラメーターのデータを格納する構造体は、パラメーター オブジェクト K1 を表すフィールド K1 を 1 つ定義しています。

rtwdemodbtype(file,'/* Parameters (default storage) */',...
    '/* Real-time Model Data Structure */',1,0)
/* Parameters (default storage) */
struct P_rtwdemo_basicsc_T_ {
  real32_T K1;                         /* Variable: K1
                                        * Referenced by: '<Root>/Gain'
                                        */
};

生成されたインターフェイスによるデータへのアクセス

標準化されたインターフェイスを介してモデル データにアクセスするために、生成コードに追加のコードやファイルを含めるように設定できます。たとえば、信号のデータをログに記録したり実行時にパラメーターを調整したりするには C API を使用します。

`.次のカスタム ソース コードを現在のフォルダーの ex_myHandCode.c という名前のファイルにコピーします。

#include "ex_myHandHdr.h"
 
#define paramIdx 0 /* Index of the target parameter, 
determined by inspecting the array of structures generated by the C API. */
#define sigIdx 0 /* Index of the target signal, 
determined by inspecting the array of structures generated by the C API. */
 
void tuneFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr)
{
    /* Take action with the parameter value only at 
       the beginning of simulation and at the 5-second mark. */
    if (*tPtr == 0 || *tPtr == 5) {
        
        /* Local variables to store information extracted from 
           the model mapping information (mmi). */
        void** dataAddrMap;
        const rtwCAPI_DataTypeMap *dataTypeMap;
        const rtwCAPI_ModelParameters *params;
        int_T addrIdx;
        uint16_T dTypeIdx;
        uint8_T slDataType;
        
        /* Use built-in C API macros to extract information. */
        dataAddrMap = rtwCAPI_GetDataAddressMap(mmi);
        dataTypeMap = rtwCAPI_GetDataTypeMap(mmi);
        params = rtwCAPI_GetModelParameters(mmi);
        addrIdx = rtwCAPI_GetModelParameterAddrIdx(params,paramIdx);
        dTypeIdx =  rtwCAPI_GetModelParameterDataTypeIdx(params,paramIdx);
        slDataType = rtwCAPI_GetDataTypeSLId(dataTypeMap, dTypeIdx);
        
        /* Handle data types 'double' and 'int8'. */
        switch (slDataType) {
            
            case SS_DOUBLE: {
                real_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                /* At the 5-second mark, increment the parameter value by 1. */
                if (*tPtr == 5) {
                    (*dataAddress)++;
                }
                printf("Parameter value is %f\n", *dataAddress);
                break;
            }
            
            case SS_INT8: {
                int8_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                if (*tPtr == 5) {
                    (*dataAddress)++;
                }
                printf("Parameter value is %i\n", *dataAddress);
                break;
            }
        }
    }
}
 
void logFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr)
{
    /* Take action with the signal value only when 
       the simulation time is an integer value. */
    if (*tPtr-(int_T)*tPtr == 0) {
        
        /* Local variables to store information extracted from 
           the model mapping information (mmi). */
        void** dataAddrMap;
        const rtwCAPI_DataTypeMap *dataTypeMap;
        const rtwCAPI_Signals *sigs;
        int_T addrIdx;
        uint16_T dTypeIdx;
        uint8_T slDataType;
        
        /* Use built-in C API macros to extract information. */
        dataAddrMap = rtwCAPI_GetDataAddressMap(mmi);
        dataTypeMap = rtwCAPI_GetDataTypeMap(mmi);
        sigs = rtwCAPI_GetSignals(mmi);
        addrIdx = rtwCAPI_GetSignalAddrIdx(sigs,sigIdx);
        dTypeIdx =  rtwCAPI_GetSignalDataTypeIdx(sigs,sigIdx);
        slDataType = rtwCAPI_GetDataTypeSLId(dataTypeMap, dTypeIdx);
        
        /* Handle data types 'double' and 'single'. */
        switch (slDataType) {
            
            case SS_DOUBLE: {
                real_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                printf("Signal value is %f\n", *dataAddress);
                break;
            }
            
            case SS_SINGLE: {
                real32_T* dataAddress;
                dataAddress = dataAddrMap[addrIdx];
                printf("Signal value is %f\n", *dataAddress);
                break;
            }
        }
    }
}

2.次のカスタム ヘッダー コードを現在のフォルダーの ex_myHandHdr.h という名前のファイルにコピーします。

#include <stdio.h>
#include <string.h>
#include <math.h>
/* Include rtw_modelmap.h for definitions of C API macros. */
#include "rtw_modelmap.h"
#include "builtin_typeid_types.h"
#include "rtwtypes.h"
void tuneFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr);
void logFcn(rtwCAPI_ModelMappingInfo *mmi, time_T *tPtr);

これらのファイルでは、モデル例から生成したコードの信号やパラメーター データにアクセスするために C API を使用します。

3.モデル コンフィギュレーション パラメーター [ヘッダー ファイル] を [#include "ex_myHandHdr.h"] に、[ソース ファイル] を [ex_myHandCode.c] に設定します。

set_param('rtwdemo_basicsc','CustomHeaderCode','#include "ex_myHandHdr.h"')
set_param('rtwdemo_basicsc','CustomSource','ex_myHandCode.c')

4.モデル コンフィギュレーション パラメーター [MAT ファイルのログ] を選択します。生成された実行可能ファイルは、シミュレーションの停止時間 (モデル コンフィギュレーション パラメーターで設定) までしか実行されません。

set_param('rtwdemo_basicsc','MatFileLogging','on')

C API モデル コンフィギュレーション パラメーター [パラメーター][信号][状態][ルートレベル I/O] を選択します。

set_param('rtwdemo_basicsc','RTWCAPIParams','on')
set_param('rtwdemo_basicsc','RTWCAPISignals','on')
set_param('rtwdemo_basicsc','RTWCAPIStates','on')
set_param('rtwdemo_basicsc','RTWCAPIRootIO','on')

5.Custom Code ブロック ライブラリを読み込みます。

custcode

6.モデルに System Outputs ブロックを追加します。

add_block('custcode/System Outputs','rtwdemo_basicsc/System Outputs')

7.System Outputs ブロックのダイアログ ボックスで、[System Outputs Function 実行コード] を次のコードに設定します。

{
rtwdemo_basicsc_U.input2++;
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
tuneFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
}

8.ブロックのダイアログ ボックスで、[System Outputs Function 終了コード] を次のコードに設定します。

{
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
logFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
}

または、System Outputs ブロックの設定のために、コマンド プロンプトで以下のコマンドを使用します。

temp.TLCFile = 'custcode';
temp.Location = 'System Outputs Function';
temp.Middle = sprintf(['{\nrtwdemo_basicsc_U.input2++;'...
    '\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);'...
    '\ntuneFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));\n}']);
temp.Bottom = sprintf(['{\nrtwCAPI_ModelMappingInfo *MMI = '...
    '&(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);'...
    '\nlogFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));\n}']);
set_param('rtwdemo_basicsc/System Outputs','RTWdata',temp)

9. コードを生成します。

rtwbuild('rtwdemo_basicsc')
### Starting build procedure for: rtwdemo_basicsc
### Successful completion of build procedure for: rtwdemo_basicsc

10. コード生成レポートで、インターフェイス ファイル rtwdemo_basicsc_capi.c を表示します。このファイルは、C API を介したデータ項目の処理に使用できる構造体の配列を初期化します。たとえば、構造体 rtBlockSignals の配列では、最初の構造体 (インデックス 0) は、モデルの Gain ブロックのテスト ポイント出力信号を表します。

file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc_capi.c');
rtwdemodbtype(file,'/* Block output signal information */',...
    '/* Individual block tuning',1,0)
/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
  /* addrMapIndex, sysNum, blockPath,
   * signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
   */
  { 0, 0, TARGET_STRING("rtwdemo_basicsc/Gain"),
    TARGET_STRING(""), 0, 0, 0, 0, 0 },

  {
    0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
  }
};

addrMapIndex などの構造体のフィールドは、信号の特性を表す rtDataAddrMap など他の構造体の配列のインデックスを示します。これらの特性には、信号データのアドレス (データへのポインター)、数値データ型および信号の次元が含まれます。

11.ファイル rtwdemo_basicsc.c では、モデルの関数 step のコード アルゴリズムを表示します。アルゴリズムでは、最初に System Outputs ブロックで指定したコードが実行されます。

file = fullfile('rtwdemo_basicsc_grt_rtw','rtwdemo_basicsc.c');
rtwdemodbtype(file,'/* user code (Output function Body) */',...
    '/* Logic: ''<Root>/LogOp'' incorporates:',1,0)
  /* user code (Output function Body) */

  /* System '<Root>' */
  {
    rtwdemo_basicsc_U.input2++;
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
    tuneFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
  }

  /* DataStoreWrite: '<Root>/DSWrite' incorporates:
   *  Constant: '<Root>/Constant1'
   *  Constant: '<Root>/Constant2'
   *  Inport: '<Root>/In1'
   *  Logic: '<Root>/LogOp'
   *  RelationalOperator: '<Root>/RelOp1'
   *  RelationalOperator: '<Root>/RelOp2'
   */
  rtwdemo_basicsc_DW.mode = ((rtwdemo_basicsc_U.input1 > 10.0F) ||
    (rtwdemo_basicsc_U.input1 < -10.0F));

  /* Gain: '<Root>/Gain' incorporates:
   *  Inport: '<Root>/In2'
   *  Lookup_n-D: '<Root>/Table1'
   */
  rtwdemo_basicsc_B.Gain = rtwdemo_basicsc_P.K1 * look1_iflf_binlx
    (rtwdemo_basicsc_U.input2, rtCP_Table1_bp01Data, rtCP_Table1_tableData, 10U);

  /* Chart: '<Root>/Stateflow Chart' */
  /* Gateway: Stateflow Chart */
  /* During: Stateflow Chart */
  /* Entry Internal: Stateflow Chart */
  /* Transition: '<S1>:5' */
  if (rtwdemo_basicsc_DW.mode) {
    /* Transition: '<S1>:6' */
    /* Transition: '<S1>:2' */
    rtwdemo_basicsc_DW.X = rtwdemo_basicsc_B.Gain;
  } else {
    /* Transition: '<S1>:4' */
  }

  /* Outport: '<Root>/Out1' incorporates:
   *  Chart: '<Root>/Stateflow Chart'
   */
  /* Transition: '<S1>:3' */
  rtwdemo_basicsc_Y.Out1 = (real32_T)(rtwdemo_basicsc_DW.X * 3.0);

  /* Lookup_n-D: '<Root>/Table2' incorporates:
   *  Inport: '<Root>/In3'
   *  Inport: '<Root>/In4'
   */
  rtwdemo_basicsc_DW.X = look2_iflf_binlx(rtwdemo_basicsc_U.input3,
    rtwdemo_basicsc_U.input4, rtCP_Table2_bp01Data, rtCP_Table2_bp02Data,
    rtCP_Table2_tableData, rtCP_Table2_maxIndex, 3U);

  /* user code (Output function Trailer) */

  /* System '<Root>' */
  {
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
    logFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
  }

  /* Matfile logging */
  rt_UpdateTXYLogVars(rtwdemo_basicsc_M->rtwLogInfo,
                      (&rtwdemo_basicsc_M->Timing.taskTime0));

  /* signal main to stop simulation */
  {                                    /* Sample time: [1.0s, 0.0s] */
    if ((rtmGetTFinal(rtwdemo_basicsc_M)!=-1) &&
        !((rtmGetTFinal(rtwdemo_basicsc_M)-rtwdemo_basicsc_M->Timing.taskTime0) >
          rtwdemo_basicsc_M->Timing.taskTime0 * (DBL_EPSILON))) {
      rtmSetErrorStatus(rtwdemo_basicsc_M, "Simulation finished");
    }
  }

  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   * Timer of this task consists of two 32 bit unsigned integers.
   * The two integers represent the low bits Timing.clockTick0 and the high bits
   * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
   */
  if (!(++rtwdemo_basicsc_M->Timing.clockTick0)) {
    ++rtwdemo_basicsc_M->Timing.clockTickH0;
  }

  rtwdemo_basicsc_M->Timing.taskTime0 = rtwdemo_basicsc_M->Timing.clockTick0 *
    rtwdemo_basicsc_M->Timing.stepSize0 + rtwdemo_basicsc_M->Timing.clockTickH0 *
    rtwdemo_basicsc_M->Timing.stepSize0 * 4294967296.0;
}

/* Model initialize function */
void rtwdemo_basicsc_initialize(void)
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)rtwdemo_basicsc_M, 0,
                sizeof(RT_MODEL_rtwdemo_basicsc_T));
  rtmSetTFinal(rtwdemo_basicsc_M, 10.0);
  rtwdemo_basicsc_M->Timing.stepSize0 = 1.0;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    rt_DataLoggingInfo.loggingInterval = NULL;
    rtwdemo_basicsc_M->rtwLogInfo = &rt_DataLoggingInfo;
  }

  /* Setup for data logging */
  {
    rtliSetLogXSignalInfo(rtwdemo_basicsc_M->rtwLogInfo, (NULL));
    rtliSetLogXSignalPtrs(rtwdemo_basicsc_M->rtwLogInfo, (NULL));
    rtliSetLogT(rtwdemo_basicsc_M->rtwLogInfo, "tout");
    rtliSetLogX(rtwdemo_basicsc_M->rtwLogInfo, "");
    rtliSetLogXFinal(rtwdemo_basicsc_M->rtwLogInfo, "");
    rtliSetLogVarNameModifier(rtwdemo_basicsc_M->rtwLogInfo, "rt_");
    rtliSetLogFormat(rtwdemo_basicsc_M->rtwLogInfo, 0);
    rtliSetLogMaxRows(rtwdemo_basicsc_M->rtwLogInfo, 1000);
    rtliSetLogDecimation(rtwdemo_basicsc_M->rtwLogInfo, 1);

    /*
     * Set pointers to the data and signal info for each output
     */
    {
      static void * rt_LoggedOutputSignalPtrs[] = {
        &rtwdemo_basicsc_Y.Out1
      };

      rtliSetLogYSignalPtrs(rtwdemo_basicsc_M->rtwLogInfo, ((LogSignalPtrsType)
        rt_LoggedOutputSignalPtrs));
    }

    {
      static int_T rt_LoggedOutputWidths[] = {
        1
      };

      static int_T rt_LoggedOutputNumDimensions[] = {
        1
      };

      static int_T rt_LoggedOutputDimensions[] = {
        1
      };

      static boolean_T rt_LoggedOutputIsVarDims[] = {
        0
      };

      static void* rt_LoggedCurrentSignalDimensions[] = {
        (NULL)
      };

      static int_T rt_LoggedCurrentSignalDimensionsSize[] = {
        4
      };

      static BuiltInDTypeId rt_LoggedOutputDataTypeIds[] = {
        SS_SINGLE
      };

      static int_T rt_LoggedOutputComplexSignals[] = {
        0
      };

      static RTWPreprocessingFcnPtr rt_LoggingPreprocessingFcnPtrs[] = {
        (NULL)
      };

      static const char_T *rt_LoggedOutputLabels[] = {
        "output" };

      static const char_T *rt_LoggedOutputBlockNames[] = {
        "rtwdemo_basicsc/Out1" };

      static RTWLogDataTypeConvert rt_RTWLogDataTypeConvert[] = {
        { 0, SS_SINGLE, SS_SINGLE, 0, 0, 0, 1.0, 0, 0.0 }
      };

      static RTWLogSignalInfo rt_LoggedOutputSignalInfo[] = {
        {
          1,
          rt_LoggedOutputWidths,
          rt_LoggedOutputNumDimensions,
          rt_LoggedOutputDimensions,
          rt_LoggedOutputIsVarDims,
          rt_LoggedCurrentSignalDimensions,
          rt_LoggedCurrentSignalDimensionsSize,
          rt_LoggedOutputDataTypeIds,
          rt_LoggedOutputComplexSignals,
          (NULL),
          rt_LoggingPreprocessingFcnPtrs,

          { rt_LoggedOutputLabels },
          (NULL),
          (NULL),
          (NULL),

          { rt_LoggedOutputBlockNames },

          { (NULL) },
          (NULL),
          rt_RTWLogDataTypeConvert
        }
      };

      rtliSetLogYSignalInfo(rtwdemo_basicsc_M->rtwLogInfo,
                            rt_LoggedOutputSignalInfo);

      /* set currSigDims field */
      rt_LoggedCurrentSignalDimensions[0] = &rt_LoggedOutputWidths[0];
    }

    rtliSetLogY(rtwdemo_basicsc_M->rtwLogInfo, "yout");
  }

  /* block I/O */
  (void) memset(((void *) &rtwdemo_basicsc_B), 0,
                sizeof(B_rtwdemo_basicsc_T));

  /* states (dwork) */
  (void) memset((void *)&rtwdemo_basicsc_DW, 0,
                sizeof(DW_rtwdemo_basicsc_T));

  /* external inputs */
  (void)memset(&rtwdemo_basicsc_U, 0, sizeof(ExtU_rtwdemo_basicsc_T));

  /* external outputs */
  rtwdemo_basicsc_Y.Out1 = 0.0F;

  /* Initialize DataMapInfo substructure containing ModelMap for C API */
  rtwdemo_basicsc_InitializeDataMapInfo();

  /* Matfile logging */
  rt_StartDataLoggingWithStartTime(rtwdemo_basicsc_M->rtwLogInfo, 0.0,
    rtmGetTFinal(rtwdemo_basicsc_M), rtwdemo_basicsc_M->Timing.stepSize0,
    (&rtmGetErrorStatus(rtwdemo_basicsc_M)));

  /* Start for DataStoreMemory: '<Root>/Data Store Memory' */
  rtwdemo_basicsc_DW.mode = false;

  /* InitializeConditions for UnitDelay: '<Root>/Delay' */
  rtwdemo_basicsc_DW.X = 0.0F;
}

/* Model terminate function */
void rtwdemo_basicsc_terminate(void)
{
  /* (no terminate code required) */
}

このコードでは最初に、関数 step が実行されるたびに信号の値をインクリメントして入力信号 input2 に摂動を与えます。その後、コードは組み込みのマクロ rtmGetDataMapInfo を使用して、モデル データ構造体 rtwdemo_basicsc_M からモデル マッピング情報を抽出します。ポインター MMI は抽出されたマッピング情報をポイントします。これにより、関数 tuneFcn および logFcn は、C API ファイル rtwdemo_basicsc_capi.c で定義されている構造体の配列に含まれる情報にアクセスできます。

12.ファイル ex_myHandCode.c の関数 tuneFcn を表示します。この関数は、C API (モデル マッピング情報 mmi を介して) およびシミュレーション時間へのポインターを使用して、コード実行中の特定の時間にパラメーター K1 の値を出力します。シミュレーション時間が 5 秒に達すると、関数はメモリ内のパラメーター値を変更します。switch case ブロックを使用することで、関数はデータ型が int8 または double のどちらでも、パラメーター データにアクセスできます。

13. モデルの関数 step のコード アルゴリズムをもう一度表示します。関数の終わりに近づくと、アルゴリズムは System Outputs ブロックで指定したコードを実行します。このコードは関数 logFcn を呼び出します。

rtwdemodbtype(file,'/* user code (Output function Trailer) */',...
    '/* Matfile logging */',1,0)
  /* user code (Output function Trailer) */

  /* System '<Root>' */
  {
    rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_basicsc_M).mmi);
    logFcn(MMI, rtmGetTPtr(rtwdemo_basicsc_M));
  }

14. ファイル ex_myHandCode.c の関数 logFcn を表示します。この関数は C API を使用してテスト ポイントされた信号の値を出力します。関数は、データ型が single または double のどちらでも信号データにアクセスできます。

15. コマンド プロンプトで、生成された実行可能ファイル rtwdemo_bascisc.exe を実行します。

system('rtwdemo_basicsc')

パラメーターと信号値がコマンド ウィンドウの出力に表示されます。

C API などのデータ インターフェイスの詳細については、データ交換インターフェイスを参照してください。

データ アクセスの設定

目的考慮事項および詳細情報
既定で信号をアクセス可能にしてパラメーターを調整可能に設定する

モデル コンフィギュレーション パラメーター [信号ストレージの再利用] をクリアして、コンフィギュレーション パラメーター [既定のパラメーター動作][調整可能] に設定します。これらの設定により、信号のストレージが削除されず、パラメーターのインライン化が行われません。各ブロック パラメーターおよび信号線は構造体のフィールドとして生成されたコードに表示されます。これらのデータ構造の詳細については、生成されたコードによる環境とのデータ交換方法および生成されたコードによる内部信号、状態、パラメーター データの保存方法を参照してください。

[既定のパラメーター動作] の詳細については、既定のパラメーター動作を参照してください。信号のストレージを削除する最適化の詳細については、生成されたコードによる内部信号、状態、パラメーター データの保存方法およびブロック出力時の中間結果の計算と保存の最小化を参照してください。

最適化の選択後にデータ項目のアクセスと調整可能性を維持する

[信号ストレージの再利用] などの最適化を選択することでさらに効率的なコードを生成できますが、コード ジェネレーターはデータ項目の数と同数のストレージを削除します。個々のデータ項目を最適化から除外するには、次を行います。

生成されたコードで、データ項目を別個のグローバル変数として表現する

最適化を無効にすると、信号線、ブロック状態、パラメーターは、生成されたコードで構造体のフィールドとして表示されます。Embedded Coder® がないと、構造体の名前を制御できません。代わりにデータ項目を別のグローバル変数の名前、ファイルの配置およびその他の制御可能な特性に保存するには、ストレージ クラスを信号、状態または Simulink.Parameter オブジェクトに適用します。個別の信号、状態、およびパラメーター データ要素へのストレージ クラスの適用を参照してください。

データにアクセスするための標準化された C コード インターフェイスを生成する標準化されたインターフェイスを介してモデル データにアクセスするために、生成コードに追加のコードやファイルを含めるように設定できます。詳細については、C API を使用した生成コードと外部コードの間のデータ交換を参照してください。
パラメーターの調整とエクスターナル モード シミュレーション中の信号の監視

モデルからコードおよび外部の実行可能ファイルを生成する場合、エクスターナル モードでモデルのシミュレーションを実行し、実行中の実行可能ファイルと通信できます。シミュレーション中にパラメーターを調整して信号をモニターできます。ただし、このシミュレーション モードでは、コード生成に適用されるパラメーターの調整可能性の制限がシミュレーションにも適用されます。コード生成の制限事項の詳細については、生成されたコードにおけるブロック パラメーターの調整可能性の制限を参照してください。

エクスターナル モードの詳細については、エクスターナル モード シミュレーションによるパラメーターの調整と信号の監視を参照してください。

Simulink® Real-Time™ を使用してパラメーターを調整し、信号を監視する

Simulink Real-Time をご利用の場合、リアルタイム アプリケーションの実行中にパラメーターを調整して信号を監視できます。最適化をクリアしてテスト ポイントとストレージ クラスを適用することで、信号にアクセス可能にしてパラメーターを調節可能にします。Parameter Tuning with Simulink Real-Time Explorer (Simulink Real-Time)を参照してください。

制限

生成されたコードでパラメーターの調整可能性に適用される制限の詳細については、生成されたコードにおけるブロック パラメーターの調整可能性の制限を参照してください。

関連するトピック