Main Content

C コード生成のための信号データの構成

信号データは、生成されたアルゴリズム コードでブロックの入力信号からブロックの出力信号の値を計算する際に、ルートの Inport ブロックと Outport ブロックに接続する信号を除く中間結果をグローバル メモリに格納する変数で構成されます。信号データはモデルのブロック線図の信号線ではありません。たとえば、次のような場合は、生成コードに信号線のデータ表現は含まれません。

  • 関数呼び出し端子に入る

  • Send ブロックなどのメッセージ ブロックから出る

  • 計算ブロックを介さずにサブシステムの境界をまたぐ

コード生成用にモデルを構成する際、生成コードでアクセス可能にするブロックの入力信号と出力信号を選択します。たとえば、次のような目的で信号データを構成します。

  • 生成コードの実行中に操作および監視するためにデータをアクセス可能にする。

  • メモリに格納されるデータの量を最小限に抑える。

  • コード ジェネレーターが信号データをメモリ内のどこに配置するかを制御する。

  • 信号データをモデル インターフェイスにプロモートし、他のコンポーネントおよびシステムがそのデータにアクセスできるようにする。

  • 生成されたコードの可読性およびトレーサビリティを向上させる。

コード ジェネレーターは信号線の構成の整合性をチェックします。たとえば、コード ジェネレーターは、サブシステムに入る信号線の構成について、対応するサブシステムの入力端子を出る信号線の構成と一致することを検証します。

コード生成について、この例ではモデル rtwdemo_configrpinterface のブロックの信号を構成する方法を説明します。コード マッピング エディター – C またはコード マッピング プログラミング インターフェイス (coder.mapping.api.CodeMapping) を使用してコード マッピングを構成できます。

信号についてのコード構成オプションの選択

コード生成の要件に応じて、生成コードで表現するブロックの信号と、その信号データの表現方法を決定します。既定では、モデルの信号は、生成されたコードでは model_B という名前のグローバル データ構造体のフィールドとして表示されます。カスタマイズを構成しない場合、コード ジェネレーターは生成されたコード内の信号の表現を最適化目的で削除するか変更するかを判断します。カスタマイズを構成する場合は、以下を決定します。

  • 生成されたコードでアクセス可能にする信号

    生成されたコードでアクセス可能にする信号は、モデル コード マッピングに追加する必要があります。

  • 既定の構成を設定するかどうか

    多数の信号 (10 を超えるなど) へのアクセスを取得する必要がある場合、既定の設定で信号を構成してから、その設定を特殊なケースについてオーバーライドすると効率的です。固有のソース、命名規則、または配置要件をもつ少数の信号へのアクセスを取得する必要がある場合は、それらの信号を個別に構成することを検討します。

  • 生成されたコードでの信号データの宣言と取り扱いの方法

    • 個別のグローバル変数として

    • 外部コードで定義されているグローバル変数から入力データを読み取るため

    • アクセス関数への呼び出しとして。Embedded Coder® が必要

    これらのオプションの詳細については、生成コードでのデータと関数インターフェイスの制御を参照してください。

その他の考慮事項には次のものがあります。

信号とそれに対応するストレージ クラスとストレージ クラスのプロパティに関連するインターフェイス要件のリストについては、Choose Storage Class and Storage Class Properties for Data Storesを参照してください。

モデル例 rtwdemo_configrpinterface の信号の要件は次のとおりです。

  • Switch ブロックに出入りする信号をコード生成用に構成する。生成コードの実行中に監視できるように信号データを保持する。

  • 信号を個別のグローバル変数として表現する。

  • 信号を表す変数の名前に接頭辞 dout_ を適用する。

生成されたコードでの既定の信号の表現を static 型修飾子をもつグローバル変数として設定します。次に、2 つの Lookup Table ブロックの出力信号について、既定のストレージ クラスと必須の接頭辞 dout_ を含む一意のコード識別子を使用するように構成します。

信号をモデル コード マッピングに追加

コード生成用に信号を構成する前に、信号をモデル コード マッピングに追加します。モデル コード マッピングに 2 つの Lookup Table ブロックの出力信号を追加します。

  1. モデル例 rtwdemo_configrpinterface を開きます。書き込み可能な場所にモデルのコピーを保存します。

    Simulink model to use for learning how to configure signals for code generation.

  2. Simulink Coder アプリを開きます。

  3. [C コード] タブで、[コード インターフェイス][個々の要素コードのマッピング] を選択します。

  4. コード マッピング エディターで、[信号/状態] タブをクリックします。リストされた信号はありません。

  5. コード マッピングに信号を追加します。Lookup Table ブロック Table1 および Table2 の出力信号について次を実行します。

    1. モデルで信号を選択します。

    2. 信号線の上または下に表示される省略記号上で一時停止してアクション バーを開きます。[信号の追加] ボタンをクリックします。

      Action bar that appears over signal line when you pause on ellipsis.

    コード マッピング エディターで、[信号] ノードが展開され、追加した 2 つの信号がリストされます。

    Code Mappings editor with Signals/States tab selected and Signals tree node expanded, listing signals Table1:1 and Table2:1.

信号に対する既定のコード生成設定の構成

信号の既定のコード生成設定を使用すると、生成されたコードの実行中に監視する信号が多数あるモデルの場合は特に、コード生成のためのモデルの準備作業を軽減できます。構成設定を一度選択すると、コード ジェネレーターによってそれらの設定がモデル全体の信号に適用されます。Simulink® は既定の構成をモデルの一部として保存します。

固有の要件がない複数の信号をモデルで使用する場合は、モデルの信号について既定のコード生成設定を構成することを検討します。

この例では、コード マッピング エディター – C を使用して、モデル rtwdemo_configrpinterface の信号に対する既定のストレージ クラスを ExportedGlobal に設定する方法を示します。ストレージ クラス設定をそのようにすると、コード ジェネレーターは、生成されたコードで信号データをグローバル変数として表します。

  1. まだ実行していない場合は、信号をモデル コード マッピングに追加の説明に従って、信号をモデル コード マッピングに追加します。

  2. [C コード] タブで、[コード インターフェイス][既定のコード マッピング] を選択します。

  3. コード マッピング エディターの [データの既定の設定] タブで、[信号] の下にあるカテゴリ [Signals, states, and internal data] を選択します。既定のストレージ クラスを [ExportedGlobal] に設定します。

    Code Mappings editor with Data Defaults tab selected, Signals tree node expanded, and storage class for Signals, states, and internal data set to ExportedGlobal.

  4. モデルを保存します。

個別の信号に対するコード生成設定の構成

コード生成についての個別の信号を構成できます。たとえば、モデルに固有のコード生成要件をもつ信号が 2 つある場合、信号を個別に構成します。または、信号について既定の設定を構成する場合、特定の信号についてその設定をオーバーライドできます。

モデルが以下の条件のうち少なくとも 1 つを満たす場合、信号に対して個別にコード生成設定を構成することを検討してください。

  • 固有のソース、命名規則、または配置要件をもつ複数の信号を使用する。

  • 少数の信号を使用する。

  • 信号について既定の構成があり、いくつかの固有の信号についてその構成をオーバーライドする必要がある。

この例では、コード マッピング エディターを使用して、既定のストレージ クラス設定をモデル rtwdemo_configinterface 内の Lookup Table ブロック Table1 および Table2 の出力信号に適用する方法を示します。この例では、それらの出力信号に対するコード識別子を構成する方法も示します。コード生成識別子は、たとえば統合用に、モデル設計の変更を伴わずに指定できます。

  1. まだ実行していない場合は、信号に対する既定のコード生成設定の構成の手順を完了します。

  2. コード マッピング エディターで、[信号/状態] タブをクリックします。[信号] を展開します。エディターで、コード マッピングに追加した信号の名前またはブロック端子識別子がリストされます。信号が信号オブジェクトに関連付けられる場合、信号オブジェクトへの関連付けアイコンが要素名または端子識別子の右側に表示されます。各信号のストレージ クラスは Auto に設定されています。これは、コード ジェネレーターが最適化を目的として関連するコードの表現を削除または変更する可能性があることを意味しています。最適化が不可能な場合、コード ジェネレーターはモデルの既定の構成を適用します。この例の場合、モデルの既定の構成はストレージ クラス ExportedGlobal を指定します。

    • 最適化を回避し、コード ジェネレーターで既定の構成が強制的に使われるようにするには、ストレージ クラスを [Model default] に設定します。

    • 既定の構成をオーバーライドするには、その信号のコード生成に関する要件を満たすストレージ クラスを指定します。

  3. コード マッピング エディターで、Table1 ブロックと Table2 ブロックの出力信号を選択します。ストレージ クラスを [Model default:ExportedGlobal] に設定します。

  4. 2 つの Lookup Table ブロックの出力信号に対するコード識別子を接頭辞 dout_ を含む名前で構成します。コード マッピング エディターで、信号 Table1:1 を選択します。Icon to configure additional code mapping properties アイコンをクリックして、[識別子] プロパティを dout_Table1 に設定します。信号 Table2:1 について、[識別子]dout_Table2 に設定します。

    Code Mappings editor with Signals/States tab selected, Signals tree node expanded, and storage class for signals Table1:1 and Table2:1 set to Model default: ExportedGlobal. Mapping Inspector shows Identifer property for signal Table1:1 set to dout_Table1.

  5. モデルを保存します。

  6. コードを生成して表示します。たとえば、rtwdemo_configrpinterface.c で、ルックアップ テーブル データのデータ定義を見つけます。

    real_T dout_Table1;                   
    real_T dout_Table2;                                         
    

    ステップ エントリポイント関数内でルックアップ テーブル データが使用されている場所を見つけます。

    .
    .
    .
       dout_Table1 = look1_binlc((*input2), (&(mp_Table1.BP[0])),
        (&(mp_Table1.Table[0])), 10U);
    	
      if (mode) {
        output = (real_T)mp_K1 * dout_Table1;
      } else {
        output = dstate_X;
      }
    
      dout_Table2 = look2_binlc((*input3), (*input4), (&(mp_Table2.BP1[0])),
        (&(mp_Table2.BP2[0])), (&(mp_Table2.Table[0])),
        (&(rtwdemo_configr_Table2_maxIndex[0])), 3U);}
    
      dstate_X = dout_Table2;
    }
    

信号をモデル コード マッピングから削除

  1. [C コード] タブで、[コード インターフェイス][個々の要素コードのマッピング] を選択します。

  2. コード マッピング エディターで、[信号/状態] タブをクリックします。

  3. 削除する信号ごとに次を実行します。

    1. モデルで信号を選択します。

    2. 信号線の上または下に表示される省略記号上で一時停止してアクション バーを開きます。[信号の削除] ボタンをクリックします。

信号に対するコード生成設定のプログラムによる構成

コード生成のための信号の構成を自動化するには、コード マッピングのプログラミング インターフェイスを使用します。たとえば、カスタム ブロック ライブラリまたはアプリケーション テスト環境の一部を作成する場合は、プログラミング インターフェイスを使用してデータの構成を自動化します。

この例では、プログラミング インターフェイスを使用して、モデル rtwdemo_configrpinterface の信号を構成する方法を示します。生成されたコードでの既定の信号の表現をグローバル変数として設定します。次に、2 つの Lookup Table ブロックの出力信号について、既定のストレージ クラスと必須の接頭辞 dout_ を含む一意のコード識別子を使用するように構成します。

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

    open_system('rtwdemo_configrpinterface')
    
  2. 関数 coder.mapping.api.get を呼び出してオブジェクト cm を作成します。オブジェクトは、モデル rtwdemo_configrpinterface のデータのコード生成構成を保存します。

    cm = coder.mapping.api.get('rtwdemo_configrpinterface');
  3. 関数 setDataDefault を呼び出して信号の既定の設定を構成します。引数には、次の値を指定します。

    • coder.mapping.api.get で返されるオブジェクト

    • 既定のカテゴリの InternalData

    • プロパティ値 ExportedGlobal をもつプロパティ名 StorageClass

    setDataDefault(cm,'InternalData','StorageClass','ExportedGlobal');
  4. 信号の既定の構成を検証します。coder.mapping.api.get およびカテゴリ InternalData によって返されるオブジェクトを指定する getDataDefault の呼び出しを発行します。3 番目の引数をプロパティ StorageClass として指定します。

    getDataDefault(cm,'InternalData','StorageClass')
    
    ans =
    
        'ExportedGlobal'
    
  5. Lookup Table ブロック Table1 および Table2 の出力端子へのハンドルを取得します。端子ハンドルは、信号データをモデル コード マッピングに追加するために使用します。

    lut1D_ports = get_param('rtwdemo_configrpinterface/Table1','PortHandles');
    lut2D_ports = get_param('rtwdemo_configrpinterface/Table2','PortHandles');
    
    lut1D_outPort = lut1D_ports.Outport;
    lut2D_outPort = lut2D_ports.Outport;
    
  6. モデル コード マッピングに Lookup Table ブロックの出力信号を追加します。

    addSignal(cm,[lut1D_outPort,lut2D_outPort]);
    
  7. 信号に対する既定の構成を Lookup Table ブロックの出力信号に適用します。

    既定では、Simulink は個別の信号のストレージ クラスを Auto に設定します。コード ジェネレーターは次を行います。

    • 最適化目的で生成されたコードからデータを削除するかどうかを決定する。

    • データを保持する場合、既定の構成設定を考慮して、生成されたコード内でデータを効率的に表す方法を決定する。

    信号の構成を制御するには、関数 setSignal を呼び出します。

    それぞれの信号について、次を指定する setSignal への呼び出しを発行します。

    • coder.mapping.api.get によって返されるオブジェクト

    • 信号の端子ハンドル lut1D_outport または lut2D_outport

    • 信号に対してプロパティ StorageClass およびプロパティ値 Model default を使用して以前に設定された既定のストレージ クラス。

    • プロパティ Identifier およびプロパティ値 dout_Table1 または dout_Table2

    setSignal(cm,lut1D_outPort,'StorageClass','Model default','Identifier','dout_Table1');
    setSignal(cm,lut2D_outPort,'StorageClass','Model default','Identifier','dout_Table2');
    
  8. 関数 getsignal を呼び出して構成の設定を検証します。coder.mapping.api.get から返されるオブジェクト、信号の端子ハンドル (lut1D_outport または lut2D_outport)、およびプロパティ StorageClass または Identifier を指定します。

    getSignal(cm,lut1D_outPort,'StorageClass')
    
    ans =
    
        'Model default'
    
    getSignal(cm,lut1D_outPort,'Identifier')
    
    ans =
    
        'dout_Table1'
    
    getSignal(cm,lut2D_outPort,'StorageClass')
    
    ans =
    
        'Model default'
    
    getSignal(cm,lut2D_outPort,'Identifier')
    
    ans =
    
        'dout_Table2'
    
  9. モデルを保存します。

  10. コードを生成して表示します。たとえば、rtwdemo_configrpinterface.c で、ルックアップ テーブル データのデータ定義を見つけます。

    real_T dout_Table1;                   
    real_T dout_Table2;                                         
    

    ステップ エントリポイント関数内でルックアップ テーブル データが使用されている場所を見つけます。

    .
    .
    .
       dout_Table1 = look1_binlc((*input2), (&(mp_Table1.BP[0])),
        (&(mp_Table1.Table[0])), 10U);
    	
      if (mode) {
        output = (real_T)mp_K1 * dout_Table1;
      } else {
        output = dstate_X;
      }
    
      dout_Table2 = look2_binlc((*input3), (*input4), (&(mp_Table2.BP1[0])),
        (&(mp_Table2.BP2[0])), (&(mp_Table2.Table[0])),
        (&(rtwdemo_configr_Table2_maxIndex[0])), 3U);}
    
      dstate_X = dout_Table2;
    }
    

信号のストレージ クラスおよびストレージ クラス プロパティの選択

コード生成の要件に応じて、ブロックの信号に対してコード生成を構成するストレージ クラスを次から選択します。

要件選択するストレージ クラス
より効率的なコードを生成するように、最適化を有効にします。Auto (個別のマッピングのみ)
最適化できないデータ要素の場合、データを標準のデータ構造体のフィールドとして表します。既定値 (既定のマッピングのみ)
最適化によってデータ要素のストレージが削除されるのを防ぎ、データ要素のカテゴリに対して既定のストレージ クラスを使用します。Model Default (個別のマッピングのみ)、Dictionary Default (個別のマッピングのみ)
グローバル変数の定義と宣言を生成します。ExportedGlobal
外部コードで定義されたグローバル変数またはグローバル変数のポインターに対して読み取りと書き込みを実行するコードを生成します。ImportedExtern、ImportedExternPointer

使用可能なストレージ クラスのリストには、Embedded Coder ディクショナリで定義された他のプロジェクト固有のストレージ クラスが含まれている可能性があります。リストされているストレージ クラスでは満たされない特別な要件がある場合、Embedded Coder ソフトウェアをお持ちであれば、ストレージ クラスを定義できます。Define Storage Classes, Memory Sections, and Function Templates for Software Architecture (Embedded Coder)を参照してください。

個別の信号については、[識別子] ストレージ クラス プロパティを使用して、生成されたコードで信号を表す変数の名前を構成します。

参考

|

関連するトピック