メインコンテンツ

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

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

列挙データ型

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

次の MATLAB クラス定義では、BasicColors という名前の列挙データ型を定義しています。

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

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

列挙データ型を定義する方法の選択

列挙データ型の定義には次の方法を使用できます。

次の表は、列挙データ型定義の条件と要件を抽出したリストです。それぞれについて、推奨される方法を示しています。

条件または要件classdef ブロック MATLAB ファイルSimulink.defineInEnumType 関数Simulink.importExternalCTypes Function
データ型定義を MATLAB スクリプト ファイルで定義する。X  
メソッド、コールバック、プロパティ、その他のカスタムの情報など、コンテンツを追加してデータ型定義を拡張する。 X  
基底クラスから定義を派生させる。X  
複数のデータ型定義を 1 つのファイルに格納する。 X 
単一の MATLAB セッション内で実行される複数の実行にわたって、悪影響を及ぼすことなくデータ型定義を変更する。 X 
外部の C ヘッダー ファイルにある既存のデータ型定義を使用する。  X

これらの方法の詳細については、Simulink モデルでの列挙型データの使用および該当する関数のリファレンス ページを参照してください。

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

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

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

  • 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 — 生成コードでクラス名を接頭辞にするかどうかを指定します。

  • isTunableInCode — 列挙値が生成コードで調整可能かどうかを指定します。

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

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

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

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

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

説明の指定

Embedded Coder® のライセンスをお持ちの場合は、[Simulink データ オブジェクトの説明] (Embedded Coder) モデル コンフィギュレーション パラメーターを有効にして、生成されたコードに列挙データ型の説明を含めることができます。列挙データ型用の説明を指定するには、このメソッドを列挙型のクラスの 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 は列挙型の名前のそれぞれに接頭辞として表示されます。

生成コードにおける列挙データ型の調整可能性の構成

R2025a 以降

MATLAB 環境の外部のヘッダー ファイルで定義された列挙データ型定義をインポートする場合は、列挙値を生成コードで調整可能にするかどうかを制御できます。調整可能な列挙値を使用すると、マスター データ ディクショナリで提供される定義などのデータ型定義をアプリケーション間で共有できます。必要に応じて、各アプリケーションの要件に合わせて、列挙値を生成コードで変更、追加、並べ替えることができます。

既定では、生成コード内の列挙値は調整可能ではありません。列挙型の調整可能性を有効にするには、メソッド getHeaderFilegetDataScopeisTunableInCode を列挙クラスの methods(Static) セクションに含めます。

  • getHeaderFile は、生成コード内の列挙型を定義する外部ファイルを指定します。指定されたファイルの重要性が getDataScope メソッドで判断されます。

  • getDataScope は、列挙型定義を生成コードでインポートするのかエクスポートするのかを指定します。このメソッドは以下を返します。

    • 型定義をインポートするための外部ヘッダー ファイルが getHeaderFile で指定されているかどうかに応じて、ヘッダー ファイルをインポートするかヘッダー ファイル model_types.h を生成するかをコード ジェネレーターで選択する場合は Auto

    • 生成されるヘッダー ファイル model_types.h のデータ型をコード ジェネレーターで定義する場合は Exported

    • 指定された外部ヘッダー ファイルからコード ジェネレーターでデータ型定義をインポートする場合は Imported

  • isTunableInCode は、列挙値に定義された値が調整可能かどうかを指定します。

次に示す列挙クラスの methods(Static) セクションの例では、生成コードで imported_enum_type.h から型定義をインポートするように指定し、インポートされた列挙型の値の生成コードでの調整可能性を有効にしています。調整可能性を無効にするには、メソッド isTunableInCode で戻り値 false を指定します。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(2)
  end
  methods (Static = true)
    function retVal = getDataScope()
      retVal = "Imported";
    end    
    function retVal = getHeaderFile()
      retVal = "imported_enum_type.h";
    end
    function retVal = isTunableInCode()
      retVal = true;
    end
  end
end

調整可能な列挙型に対して定義される各列挙値に関連付けられた数値は一意でなければなりません。たとえば、次の列挙クラスは、数値 1 に列挙値 YellowBlue が関連付けられているため無効です。

classdef BasicColors < Simulink.IntEnumType
  enumeration
    Red(0)
    Yellow(1)
    Blue(1)
  end
  methods (Static = true)
    function retVal = getDataScope()
      retVal = "Imported";
    end    
    function retVal = getHeaderFile()
      retVal = "imported_enum_type.h";
    end
    function retVal = isTunableInCode()
      retVal = true;
    end
  end
end

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

ヘッダー ファイルから列挙型データをインポートするとき、コード生成中に重複する列挙型メンバー名を使用するかを制御できます。重複する列挙型メンバー名は、コードの可読性を向上させます。モデル コンフィギュレーション パラメーター [重複する列挙型メンバー名] を使用して、コード生成中に異なる列挙型で重複する列挙型メンバー名を許可するか、エラーまたは警告メッセージを生成します。重複する列挙型メンバー名は、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

MATLAB 名前空間内で列挙型を定義する場合、コード ジェネレーターは、既定では C++ コード生成の名前空間で列挙値を生成します。C コード生成の場合、コード ジェネレーターは列挙値の前に MATLAB 名前空間の接頭辞を付けます。生成コードでの C++ 名前空間と C 接頭辞の生成を無効にするには、モデル コンフィギュレーション パラメーター [生成コード内での MATLAB 名前空間の保持] (Embedded Coder) をクリアします。

次の表は、[生成コード内での MATLAB 名前空間の保持] を選択した場合とクリアした場合について、MATLAB 名前空間 MyColors の列挙型 Colors の生成コードを示したものです。

言語選択クリア
C
typedef enum {
    black,
    white,
} MyColors_Colors;
typedef enum {
    black,
    white
}  Colors;
C++
namespace MyColors {
    enum class Colors : int32_t {
        black,
        white
    };
}
enum class Colors : int32_t {
        black,
        white
    };

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

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 には列挙型の型定義が含まれます。

列挙値の型キャスト

安全なキャスト

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

入力値が列挙型の値の元となる値と一致しない場合には、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") 以下でなければなりません。

  • 生成コード内の調整可能な列挙値については次のようになります。

    • データ型定義はインポートする必要があります。

    • データ型定義に重複する列挙メンバー名を含めることはできません。

    • 調整可能な列挙型の実行時パラメーターにつながる値の場合、数値または空の値 (0 や [] など) を使用してパラメーターを指定することはできません。

    • 折りたたまれることがある調整可能な列挙値を含むパラメーター式はサポートされていません。

    • 生成コードでは、元となる列挙値に基づく範囲解析は実行されません。

    • 調整可能な列挙型に対して定義される各列挙値に関連付けられた数値は一意でなければなりません。

    • AUTOSAR インターフェイス タイプでは、インターフェイス タイプがヘッダー ファイル Rte_Type.h に出力するように構成されている場合、調整可能な列挙型はサポートされません。

参考

| | | |

トピック