Main Content

非バーチャル サブシステムのモジュラー関数コードの生成

非バーチャル サブシステムのコード生成について

既定では、非バーチャル サブシステムのコードを作成すると、コード ジェネレーターによって、非バーチャル サブシステムに関連付けられた内部データが親モデルの内部データと同じデータ構造体に配置されます。これにより、特に再利用できないサブシステムの場合は、コードをトレースおよびテストするのが困難になる場合があります。また、非バーチャル サブシステムを含む大規模なモデルでは、データ構造体が大きくなり、コンパイルが難しくなる可能性があります。

Atomic サブシステムや条件付き実行サブシステムを含む、非バーチャル サブシステムのモジュラー関数コードを生成するには、Subsystem ブロック パラメーターの [別々のデータをもつ関数] を使用します。このブロック パラメーターは、コード ジェネレーターに対し、親モデルのデータ構造体に依存しない非バーチャル サブシステム関数のブロック I/O と DWork データ構造体を生成するように指示します。その結果、サブシステムに対して生成されたコードは次のようになります。

  • 簡単にトレースできる。

  • 簡単にテストできる。

  • モデルのグローバル データ構造体のサイズが削減される。

[別々のデータをもつ関数] パラメーターを使用するには、次を実行します。

  • ERT ベースのシステム ターゲット ファイルを使用してモデルを設定する。

  • サブシステムが Atomic または条件付き実行になるように設定する。

  • Subsystem ブロック パラメーター [関数のパッケージ化][再利用できない関数] に設定する。

モジュラー関数コードを生成するためにサブシステムを構成するには、[Subsystem パラメーター] ダイアログ ボックスを開き、表示されている一連の選択を行い、[別々のデータをもつ関数] オプションを有効にします。詳細については、モジュラー関数コードを生成するためのサブシステムの設定非バーチャル サブシステムのモジュラー関数コードを参照してください。適用される制限については、非バーチャル サブシステム モジュラー関数コードの制限を参照してください。

Atomic サブシステムのコードの生成の詳細については、サブシステム コードを別々の関数およびファイルとして生成および個別のサブシステムのコードと実行可能ファイルの生成を参照してください。

モジュラー関数コードを生成するためのサブシステムの設定

  1. サブシステムを含むモデルが ERT ベースのシステム ターゲット ファイルを使用しているか確認します。

  2. モジュラー関数コードを生成するサブシステムを選択し、[Subsystem パラメーター] ダイアログ ボックスを開きます。Atomic サブシステムのダイアログ ボックスを以下に示します (条件付き実行サブシステムのダイアログ ボックスでは、ダイアログ ボックス オプション [Atomic サブシステムとして扱う] がグレー表示になり、手順 3 を省略できます)。

  3. ブロック パラメーター [Atomic サブシステムとして扱う] が選択可能であっても選択されていない場合、サブシステムは Atomic サブシステムにも条件付き実行サブシステムにもなりません。パラメーター [Atomic サブシステムとして扱う] を選択します。これにより、[コード生成] タブの [関数のパッケージ化] パラメーターが有効になります。[コード生成] タブを選択します。

  4. [関数のパッケージ化] パラメーターの場合は、[再利用できない関数] を選択します。この選択を行った後、[別々のデータをもつ関数] パラメーターが表示されます。

    [別々のデータをもつ関数] パラメーターを選択して非バーチャル サブシステムのコードを生成する前に、このパラメーターをオフにして関数コードを生成し、後で比較できるように .c ファイルおよび .h ファイルを別のディレクトリに保存しておくことを検討してください。

  5. [別々のデータをもつ関数] パラメーターを選択します。追加のパラメーターが表示されます。

    生成されるサブシステム関数とサブシステム ファイルの命名を制御するために、サブシステム パラメーター [関数名オプション] [ファイル名オプション] を変更します。

  6. サブシステム パラメーターの変更を保存し、[OK] をクリックしてダイアログ ボックスを終了します。

  7. サブシステムのコードを生成し、サブシステム パラメーターの指定に従って命名した関数 .c ファイルおよび .h ファイルを含む、生成されたファイルを調べます。

非バーチャル サブシステムのコード生成の詳細については、サブシステム コードを別々の関数およびファイルとして生成を参照してください。生成されたサブシステムの関数コードの例については、非バーチャル サブシステムのモジュラー関数コードを参照してください。

非バーチャル サブシステムのモジュラー関数コード

この例では、[別々のデータをもつ関数] パラメーターを無効および有効にして非バーチャル サブシステムの関数コードを生成し、その結果を比較する方法を示します。

  1. モデル例 SubsystemAtomic を開きます。

  2. Embedded Coder アプリを開きます。システム ターゲット ファイルを ert.tlc に変更します。

    このモデルでは、バーチャル サブシステムの境界を保持する方法を説明します。Subsystem ブロック パラメーター [Atomic サブシステムとして扱う] を選択すると、サブシステムのコード ジェネレーターによって生成されるコードは、Atomic サブシステムとして実行されます。Atomic として設定した場合、[コード生成] タブの [関数のパッケージ化] パラメーターを設定して、コード ジェネレーターでのサブシステムの表現方法を指定できます。サブシステムが次のいずれかの実装タイプに変換されることを指定できます。

    • インライン: 呼び出しサイトでインライン化されたサブシステム コード。

    • 関数: モデルのグローバル データ構造体に I/O および内部データをもつ void/void 関数。

    • 再利用可能な関数: データが関数の引数として渡される再呼び出し可能な関数。

    • 自動: コードジェネレーターで、コンテキストに基づいて実装が最適化されます。

  3. SS1 サブシステムをダブルクリックし、内容を確認します。

    その後、サブシステム ウィンドウを閉じます。

  4. SS1 サブシステムを右クリックし、コンテキスト メニューから [ブロック パラメーター (Subsystem)] を選択して、設定を調べます。サブシステム パラメーター [代数ループの発生の最小化] を使用してサブシステムを Atomic にしている場合、Simulink® およびコード ジェネレーターでは、"人為的な" 代数ループを避けることができます。

  5. データの分離を "使用しない" 関数コードを示す SubsystemAtomic のバリアントを作成します。

    1. [Subsystem パラメーター] ダイアログ ボックスで、次を行います。

      • [メイン] タブで、[Atomic サブシステムとして扱う] を選択します。

      • [コード生成] タブで、次を行います。

        • [関数のパッケージ化][再利用可能な関数] に設定します。

        • [関数名オプション][ユーザー指定] に設定します。

        • [関数名]myfun に設定します。

        • [ファイル名オプション][関数名を使用] に設定します。この設定はオプションですが、Atomic サブシステムの関数コードがファイル myfun.cmyfun.h に生成されるようにして、後からコード比較のタスクを簡略化することができます。

      [別々のデータをもつ関数] パラメーターは "選択しない" でください。

    2. [適用] をクリックして変更を適用し、[OK] をクリックしててダイアログ ボックスを閉じます。

    3. モデル バリアントを一意のファイル名 (SubsystemAtomic1 など) で書き込み可能な場所に保存します。

  6. データの分離を "使用する" 関数コードを示す SubsystemAtomic のバリアントを作成します。

    1. モデル SubsystemAtomic を開きます。

    2. Embedded Coder アプリを開きます。システム ターゲット ファイルを ert.tlc に変更します。

    3. モデル キャンバスで、SS1 サブシステムを右クリックし、[ブロック パラメーター (Subsystem)] を選択します。[Subsystem パラメーター] ダイアログ ボックスで、次を行います。

      • [メイン] タブで、[Atomic サブシステムとして扱う] を選択します。

      • [コード生成] タブで、次を行います。

        • [関数のパッケージ化][再利用可能な関数] に設定します。

        • [関数名オプション][ユーザー指定] に設定します。

        • [関数名]myfun に設定します。

        • [ファイル名オプション][関数名を使用] に設定します。

        • [別々のデータをもつ関数] を選択します。

    4. [適用] をクリックして変更を適用し、[OK] をクリックしててダイアログ ボックスを閉じます。

    5. モデル バリアントを一意のファイル名 (SubsystemAtomic2 など) で書き込み可能な場所に保存します。

  7. 各モデル (SubsystemAtomic1SubsystemAtomic2 など) のコードを生成します。

  8. 2 つのモデルから生成された model.c/.h ファイルと myfun.c/.h ファイルを比較します。コードの比較については、非バーチャル サブシステム関数のデータ分離での H ファイルの差および非バーチャル サブシステム関数のデータ分離での C ファイルの差を参照してください。

    この例では、ert_main.cmodel_private.hmodel_types.h、または rtwtypes.h の生成されたバリアントに有意差はありません。

非バーチャル サブシステム関数のデータ分離での H ファイルの差

  • [別々のデータをもつ関数] を選択すると、コード ジェネレーターによって、SubsystemAtomic2myfun.h ファイルにサブシステム データの型定義が配置されます。

    /* Block states (default storage) for system '<Root>/SS1' */
    typedef struct {
      real_T Integrator_DSTATE;            /* '<S1>/Integrator' */
    } DW_myfun_T;

    SubsystemAtomic1 では、次のようにサブシステム データの型定義はモデルに属し、SubsystemAtomic1.h に表示されます。

    /* Block signals (default storage) */
    typedef struct {
      real_T Sum;                          /* '<Root>/Sum' */
    } B_SubsystemAtomic_1_T;
    
    /* Block states (default storage) for system '<Root>' */
    typedef struct {
      real_T Integrator_DSTATE;            /* '<S1>/Integrator' */
    } DW_SubsystemAtomic_1_T;
  • [別々のデータをもつ関数] を選択すると、SubsystemAtomic2 について、次の外部宣言が myfun.h ファイルに生成されます。

    /* Extern declarations of internal data for system '<Root>/SS1' */
    extern DW_myfun_T myfun_DW;
    extern void myfun_Update(void);
    extern void myfun(void);

    反対に、SubsystemAtomic1 の生成されたコードは、SubsystemAtomic1.h 内にサブシステム BlockIO および D_Work データのモデルレベルの外部宣言を含みます。

    /* Block signals (default storage) */
    extern B_SubsystemAtomic_1_T SubsystemAtomic_1_B;
    
    /* Block states (default storage) */
    extern DW_SubsystemAtomic_1_T SubsystemAtomic_1_DW;

非バーチャル サブシステム関数のデータ分離での C ファイルの差

  • [別々のデータをもつ関数] を選択すると、SubsystemAtomic2 について、別のサブシステム初期化関数 myfun_initializemyfun.c ファイルに生成されます。

    void myfun_initialize(void) {
      {
        ((real_T*)&SubsystemAtomic2_myfunB.Integrator)[0] = 0.0;
      }
      SubsystemAtomic2_myfunDW.Integrator_DSTATE = 0.0;
    }

    myfun.c のサブシステム初期化関数は、SubsystemAtomic2.c のモデル初期化関数で呼び出されます。

    /* Model initialize function */
    
    void SubsystemAtomic2_initialize(void)
    {
    ...
    
      /* Initialize subsystem data */
      myfun_initialize();
    }

    反対に、SubsystemAtomic1 の場合、サブシステムのデータは SubsystemAtomic1.c のモデル初期化関数で初期化されます。

    /* Model initialize function */
    
    void SubsystemAtomic1_initialize(void)
    {
    ...
      /* block I/O */
      {
     ...
        ((real_T*)&SubsystemAtomic1_B.Integrator)[0] = 0.0;
      }
    
      /* states (dwork) */
    
      SubsystemAtomic1_DWork.Integrator_DSTATE = 0.0;
    ...
    }
  • [別々のデータをもつ関数] を選択すると、次の宣言が SubsystemAtomic2myfun.c ファイルに生成されます。

    /* Declare variables for internal data of system '<Root>/SS1' */
    DW_myfun_T myfun_DW;

    反対に、SubsystemAtomic1 の生成されたコードは、SubsystemAtomic1.c 内にサブシステム BlockIO および D_Work データのモデルレベルの宣言を含みます。

    /* Block signals (default storage) */
    B_SubsystemAtomic_1_T SubsystemAtomic_1_B;
    
    /* Block states (default storage) */
    DW_SubsystemAtomic_1_T SubsystemAtomic_1_DW;
  • [別々のデータをもつ関数] を選択すると、データ項目のサブシステムの方向を反映する識別子の命名が生成されます。myfunmyfun_update など、サブシステム関数内のサブシステム データへの参照は、モデルの関数 model_step 内にあります。たとえば、SubsystemAtomic2myfun にある次のコードを

    /*  DiscreteIntegrator: '<S1>/Integrator' */
      SubsystemAtomic_2_Y.Out1 = myfun_DW.Integrator_DSTATE;

    SubsystemAtomic1myfun にある対応するコードと比較します。

    /* DiscreteIntegrator: '<S1>/Integrator' */
    SubsystemAtomic_1_Y.Out1 = SubsystemAtomic_1_DW.Integrator_DSTATE;

非バーチャル サブシステム モジュラー関数コードの制限

非バーチャル サブシステム ブロック パラメーター [別々のデータをもつ関数] には次の制限があります。

  • パラメーターは、ERT ベースのシステム ターゲット ファイルで設定されたモデルで利用できる。

  • パラメーターが適用される非バーチャル サブシステムは複数のサンプル時間または連続サンプル時間をもつことができない。つまり、サブシステムは、離散サンプル時間をもつシングルレートでなければならない。

  • 非バーチャル サブシステムに連続状態を含めることはできない。

  • 非バーチャル サブシステムは、関数呼び出し信号を出力できない。

  • 非バーチャル サブシステムにインラインでない S-Function を含めることはできない。

  • 非バーチャル サブシステムの生成されたファイルは、model.hmodel_private.h などのモデル全体のヘッダー ファイルを参照する。

  • パラメーターは、[クラシック コール インターフェイス] パラメーターと互換性がない。両方のパラメーターを選択すると、エラーが発生する。

  • パラメーターは、モデル コンフィギュレーション パラメーター [コード インターフェイスのパッケージ化][再利用可能な関数] と互換性がない。両方のパラメーターを選択すると、エラーが発生する。

  • サブシステムのパラメーターを選択した場合、サブシステムを含むモデルには、[モデル インスタンス間で共有する] が選択されている Data Store Memory ブロックを含めることができない。Data Store Memory を参照してください。

関連するトピック