Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

生成されたコードにおける列挙型データの使用

列挙データ型

"列挙型データ" は決まった数の値に制約されるデータです。"列挙データ型" は、"列挙型の値" のセットを定義する MATLAB® クラスです。各列挙型の値は、ソフトウェアが生成コード内で内的に使用する "列挙型の名前" と "使用可能な整数" から構成されます。以下は BasicColors と名付けられた列挙データ型用の MATLAB クラス定義です。これはこの節の例に使用されます。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(2)
  end
end

列挙データ型と Simulink® モデル内での使用法に関する基本的な情報については、Simulink モデルでの列挙型データの使用を参照してください。Stateflow® チャート内の列挙データ型の詳細については、列挙データ型の定義 (Stateflow)を参照してください。

列挙への整数データ型の指定

列挙に対しデータ型を指定することにより以下が可能です。

  • スーパークラスの指定による生成コードでの列挙型のデータ型のサイズを制御

  • RAM/ROM の使用量の削減

  • コードの移植性の向上

  • レガシ コードとの統合の改善

次の整数データ型を指定できます。

  • int8

  • uint8

  • int16

  • uint16

  • int32

  • Simulink.IntEnumType.お使いのハードウェア プラットフォームの符号付き整数の範囲にある値を指定します。

MATLAB ファイルにおけるクラス定義の使用

整数データ型のサイズを指定するには、整数データ型から列挙型クラスを導出します。

classdef Colors < int8
   enumeration
     Red(0)
     Green(1)
     Blue(2)
   end
end

コード ジェネレーターは次のコードを生成します。

typedef int8_T Colors;

#define Red      ((Colors)0)
#define Green ((Colors)1)
#define Blue     ((Colors)2)

関数 Simulink.defineIntEnumType の使用

整数データ型のサイズを指定するには、名前と値のペア StorageType を整数データ型として指定します。

Simulink.defineIntEnumType('Colors',{'Red','Green','Blue'},...
[0;1;2],'StorageType','int8')

コード ジェネレーターは次のコードを生成します。

typedef int8_T Colors;

#define Red      ((Colors)0)
#define Green ((Colors)1)
#define Blue     ((Colors)2)

列挙データ型のカスタマイズ

列挙型データを使用するモデルからコードを生成する場合、以下の静的メソッドを実装して、シミュレーション中および生成されたコードで型の動作をカスタマイズできます。

  • getDefaultValue — 列挙データ型の既定値を指定します。

  • getDescription — 列挙データ型の記述を指定します。

  • getHeaderFile — 生成されたコードに型を定義するヘッダー ファイルを指定します。

  • getDataScope — 生成コードが列挙データ型の定義を別個のヘッダー ファイルにインポートしたり、ヘッダー ファイルからエクスポートするかどうかを指定します。

  • addClassNameToEnumNames — 生成コードでクラス名を接頭辞にするかどうかを指定します。

このメソッドのうち最初のメソッドである getDefaultValue はシミュレーションとコード生成の両方に関連しており、既定の列挙値の指定で説明されています。その他のメソッドはコード生成にのみ関連します。列挙型の動作をカスタマイズするには、メソッドのバージョンを列挙型クラス定義の methods(Static) セクションに含めます。型をカスタマイズしない場合は、methods(Static) セクションを省略します。以下の表は、メソッドとそれぞれに与えるデータの概要です。

静的メソッド目的メソッドを実装しない場合の既定値カスタムの戻り値
getDefaultValueクラスの既定の列挙型メンバーを指定します。列挙型定義で指定された最初のメンバークラスに列挙型メンバーの名前を含む文字ベクトル (列挙型のインスタンスの作成を参照)。
getDescription列挙型クラスの記述を指定します。''型の説明を含む文字ベクトル。
getHeaderFileヘッダー ファイルの名前を指定します。メソッド getDataScope は、ファイルの重要性を判断します。''

列挙型を定義するヘッダー ファイルの名前を含む文字ベクトル。

既定では、生成された #include 命令は、< および > の代わりに、プリプロセッサの区切り記号である " を使用します。命令 #include <myTypes.h> を生成するには、カスタムの戻り値を '<myTypes.h>' として指定します。

getDataScope生成コードが列挙型のデータ型の定義をインポートまたはエクスポートするかどうかを指定します。メソッド getHeaderFile を使用して、型を定義するヘッダー ファイルが生成されているか含まれているかを指定します。'Auto''Auto''Exported''Imported' のいずれか。
addClassNameToEnumNames生成コード内でクラス名に接頭辞を付けるかどうかを指定します。falsetrue または false

説明の指定

列挙データ型用の説明を指定するには、このメソッドを列挙型のクラスの methods(Static) セクションに含めます。

function retVal = getDescription() 
% GETDESCRIPTION  Optional description of the data type.
  retVal = 'description';
end

MATLAB 文字ベクトルを description に置き換えます。列挙型を定義する生成コードには指定された説明が含まれます。

生成コードでの型定義のインポート

生成コードでは列挙型のデータ型を定義せず、外部ファイルで定義されるようにするには、以下のメソッドを列挙型クラスの methods(Static) セクションに含めます。

    function retVal = getHeaderFile()
      % GETHEADERFILE Specifies the file that defines this type in generated code.
      % The method getDataScope determines the significance of the specified file.
      retVal = 'imported_enum_type.h';
    end

    function retVal = getDataScope()
      % GETDATASCOPE Specifies whether generated code imports or exports this type.
      % Return one of:
      % 'Auto':     define type in model_types.h, or import if header file specified
      % 'Exported': define type in a generated header file
      % 'Imported': import type definition from specified header file
      % If you do not define this method, DataScope is 'Auto' by default.
      retVal = 'Imported';
    end

model_types.h で型を定義する (既定の動作) のではなく、生成コードは次のように #include ステートメントを使用して指定されたヘッダー ファイルから定義をインポートします。

#include "imported_enum_type.h"

コードの生成によりインポートされたヘッダー ファイルは作成されません。列挙型のデータ型を定義するメソッド getHeaderFile によって指定されたファイル名を使用してヘッダー ファイルを提供しなければなりません。

既存の C コード列挙型に対応する Simulink 列挙型を作成するには、関数 Simulink.importExternalCTypes を使用します。

生成コードでの型定義のエクスポート

列挙型のデータ型を定義するヘッダー ファイルを別に生成するには、以下のメソッドを列挙型クラスの methods(Static) セクションに含めます。

    function retVal = getDataScope()
      % GETDATASCOPE Specifies whether generated code imports or exports this type.
      % Return one of:
      % 'Auto':     define type in model_types.h, or import if header file specified
      % 'Exported': define type in a generated header file
      % 'Imported': import type definition from specified header file
      % If you do not define this method, DataScope is 'Auto' by default.
      retVal = 'Exported';
    end

    function retVal = getHeaderFile()
      % GETHEADERFILE Specifies the file that defines this type in generated code.
      % The method getDataScope determines the significance of the specified file.
      retVal = 'exported_enum_type.h';
    end

生成コードは列挙型定義を生成されたヘッダー ファイル exported_enum_type.h にエクスポートします。

クラス名に接頭辞を追加

既定の設定では、生成コード内の列挙型の値は列挙型クラス定義内のものと同じ名前をもちます。その代わりに、コードがクラス名による接頭辞を列挙型クラス内のすべての列挙型の値に追加することもできます。この方法を使用して、識別子の競合を回避したり、コードの読みやすさを向上させることもできます。クラス名に追加する接頭辞を指定するには、このメソッドを列挙型クラスの methods(Static) セクションに含めます。

    function retVal = addClassNameToEnumNames()
      % ADDCLASSNAMETOENUMNAMES Specifies whether to add the class name
      % as a prefix to enumeration member names in generated code.
      % Return true or false.
      % If you do not define this method, no prefix is added.
      retVal = true;
    end

戻り値を true に指定して、クラス名の接頭辞追加を有効にするか、false に指定して接頭辞追加を抑制します。true を指定する場合、クラス内の列挙型の各値は、EnumTypeName_EnumName として生成コード内で表示されます。列挙データ型の列挙型クラスの例 BasicColors については、生成コード内のデータ型定義は次のようになる場合があります。

#ifndef _DEFINED_TYPEDEF_FOR_BasicColors_
#define _DEFINED_TYPEDEF_FOR_BasicColors_

typedef enum {
  BasicColors_Red = 0,            /* Default value */
  BasicColors_Yellow = 1,
  BasicColors_Blue = 2,
} BasicColors;

#endif

列挙型のクラス名 BasicColors は列挙型の名前のそれぞれに接頭辞として表示されます。

重複する列挙型メンバー名の使用の制御

ヘッダー ファイルから列挙型データをインポートするとき、コード生成中に重複する列挙型メンバー名を使用するかを制御できます。重複する列挙型メンバー名は、コードの可読性を向上させます。モデル コンフィギュレーション パラメーター [重複する列挙型メンバー名] を使用して、コード生成中に異なる列挙型で重複する列挙型メンバー名を許可するか、エラーまたは警告メッセージを生成します。重複する列挙型メンバー名は、2 つの列挙値が同一の StorageType を持ち、次の仕様を持つ場合にのみ使用できます。

  • DataScope'Imported' に設定されている

  • StorageType'int8''int16''int32''uint8''uint16' または 'uint32' に設定されている

  • Value は同じである

以下に例を示します。

typedef int32_T enum {
  Red = 0,
  Yellow = 1,
  Blue = 2,
}A;

typedef int32_T enum {
  Black = 0,
  Yellow = 1,
  White = 2,
}B;
列挙値 A および B において、メンバー名にクラス名の接頭辞を付けることなく Yellow 列挙型メンバーを持つことができ、コードの可読性を向上できます。

生成されたコードにおける列挙型の実装の制御

列挙型 BasicColors を定義するとします。以下を使用して、生成されたコードで型定義を実装するように指定できます。

  • enum ブロック。ハードウェアのネイティブ整数型は列挙型メンバーの基となる整数型です。

  • typedef ステートメントと一連の #define マクロ。typedef ステートメントは、int8 などの特定の整数データ型の列挙型名を基にします。マクロにより、列挙型メンバーは基となる整数値に関連付けられます。

enum ブロックを使用した列挙型の実装

enum ブロックを使用して型定義を実装するには、次を行います。

  • Simulink で、スクリプト ファイル内で classdef ブロックを使用し、列挙型を定義します。型 Simulink.IntEnumType から列挙型を導出します。

  • または、関数 Simulink.defineIntEnumType を使用します。プロパティ StorageType は指定しないでください。

コードを生成する場合は、enum ブロックに型定義が表示されます。

#ifndef _DEFINED_TYPEDEF_FOR_BasicColors_
#define _DEFINED_TYPEDEF_FOR_BasicColors_

typedef enum {
  Red = 0,            /* Default value */
  Yellow,
  Blue,
} BasicColors;

#endif

特定の整数型を使用した列挙型の実装

typedef ステートメントと #define マクロを使用して型定義を実装するには、次を行います。

  • Simulink で、スクリプト ファイル内で classdef ブロックを使用し、列挙型を定義します。int8 などの特定の整数型から列挙型を導出します。

  • または、関数 Simulink.defineIntEnumType を使用します。int8 などの特定の整数型を使用してプロパティ StorageType を指定します。

コードを生成すると、型定義が typedef ステートメントおよび一連の #define マクロとして表示されます。

#ifndef _DEFINED_TYPEDEF_FOR_BasicColors_
#define _DEFINED_TYPEDEF_FOR_BasicColors_

typedef int8_T BasicColors;

#define Red ((BasicColors)0)            /* Default value */
#define Yellow ((BasicColors)1)
#define Blue ((BasicColors)2)

#endif

既定では、生成されたファイル model_types.h には列挙型の型定義が含まれます。

列挙値の型キャスト

安全なキャスト

Simulink Data Type Conversion ブロックは整数型の信号を受け入れます。ブロックは入力を列挙型の元となる値のいずれかに変換します。

入力値が列挙型の値の元となる値と一致しない場合には、Simulink は安全なキャストを挿入して、入力値を列挙型の既定値に置き換えます。

安全なキャストの有効化と無効化

Simulink Data Type Conversion ブロックまたは Stateflow ブロックのコード生成において行われる列挙型の安全なキャストを有効または無効にできます。

安全なキャストを制御するには、[整数オーバーフローで飽和] ブロック パラメーターを有効または無効にします。パラメーターは以下のように動作します。

  • 有効: Simulink は、シミュレーション中に一致しない入力値を列挙値の既定値と置き換えます。安全なキャストの関数がコード生成中に生成されます。

  • 無効:一致しない入力値に対して、Simulink はシミュレーション中にエラーを生成します。安全なキャストの関数がコード生成中に省略されます。この場合、コードはより効率的になります。ただし、このコードは実行時エラーに対してはより脆弱になります。

生成コード中の安全なキャストの関数

この例では、列挙値 BasicColors に対する安全なキャストの関数 int32_T ET08_safe_cast_to_BasicColors が 32 ビット ハードウェア向けに生成される場合に、生成コードでどのように使用されているかを示しています。

static int32_T ET08_safe_cast_to_BasicColors(int32_T input)
{
	int32_T output;
	/* Initialize output value to default value for BasicColors (Red) */
	output = 0;
	if ((input >= 0) && (input <= 2)) {
	/* Set output value to input value if it is a member of BasicColors */
		output = input;
	}
	return output;
}
この関数では、入力値が列挙型の値のいずれかの元となる値と一致しなかった場合には、列挙型の既定値が使用されます。

ブロックの [整数オーバーフローで飽和] パラメーターが無効の場合には、この関数は生成コードには使用されません。

列挙型の制限

  • 生成されたコードでは、ログ列挙型データはサポートされません。

  • uint32 ベースの列挙の場合、列挙値は intmax('int32') 以下でなければなりません。

参考

| |

関連するトピック