exponenta event banner

Использование перечисляемых данных в сгенерированном коде

Перечислимые типы данных

Перечисляемые данные - это данные, которые ограничены конечным набором значений. Перечисляемый тип данных - это класс MATLAB ®, который определяет набор перечисляемых значений. Каждое перечисляемое значение состоит из перечисляемого имени и базового целого числа, которое программное обеспечение использует внутри и в сгенерированном коде. Ниже приведено определение класса MATLAB для перечисляемого типа данных с именемBasicColors, которая используется в примерах в этом разделе.

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

Основные сведения о перечисленных типах данных и их использовании в моделях Simulink ® см. в разделе Использование перечисляемых данных в моделях Simulink. Сведения о перечисленных типах данных в диаграммах Stateflow ® см. в разделе Определение перечисленных типов данных (Stateflow).

Указать целочисленный тип данных для перечисления

При указании типа данных для перечисления можно:

  • Управление размером перечисляемых типов данных в созданном коде путем указания суперкласса.

  • Сократите использование ОЗУ/ПЗУ.

  • Улучшение переносимости кода.

  • Улучшение интеграции с устаревшим кодом.

Можно указать следующие целочисленные типы данных:

  • 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, который определяет перечисляемый тип данных.

Чтобы создать перечисление Simulink, соответствующее существующему перечислению C-кода, используйте 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 в Enumerated Data Types определение типа данных в сгенерированном коде может выглядеть следующим образом:

#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 отображается как префикс для каждого из перечисляемых имен.

Управление использованием повторяющихся имен элементов перечисления

При импорте данных перечисления из файла заголовка можно управлять использованием повторяющихся имен элементов перечисления во время создания кода. Повторяющиеся имена элементов перечисления улучшают читаемость кода. Используйте параметр конфигурации модели Дублировать имена членов перечисления, чтобы разрешить дублирование имен членов перечисления в различных типах перечисления во время создания кода или для генерации сообщения об ошибке или предупреждения. Повторяющиеся имена элементов перечисления можно использовать только в том случае, если два перечисления имеют одно и то же StorageType и имеют следующие спецификации:

  • DataScope установить в значение 'Imported'

  • StorageType установить в значение 'int8', 'int16', 'int32', 'uint8', или 'uint16'

  • Value то же самое

Например:

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

typedef int32_T enum {
  Black = 0,
  Yellow = 1,
  White = 2,
}B;
Вы можете иметь Yellow элемент перечисления в перечислении A и B без префикса имени члена с именем класса для улучшения читаемости кода.

Управление реализацией перечисляемого типа в сгенерированном коде

Предположим, что определен перечисляемый тип BasicColors. Можно указать, что созданный код реализует определение типа, используя:

  • Один enum блок. Собственный целочисленный тип оборудования является базовым целочисленным типом для членов перечисления.

  • A 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. Укажите свойство StorageType с использованием определенного целого типа, такого как int8.

При создании кода определение типа отображается как 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 принимает сигнал целочисленного типа. Блок преобразует входные данные в одно из базовых значений перечисляемого типа.

Если входное значение не соответствует базовому значению перечисляемого типа, Simulink вставляет безопасную форму, чтобы заменить входное значение значением перечисляемого типа по умолчанию.

Включение и отключение безопасного литья

Можно включить или отключить безопасное приведение для перечислений во время создания кода для блока преобразования типа данных Simulink или блока потока состояний.

Для управления безопасным литьем включите или отключите параметр блока переполнения Saturate on integer. Параметр работает следующим образом:

  • Включено: Simulink заменяет несопоставляемое входное значение значением по умолчанию перечисляемых значений во время моделирования. Программное обеспечение генерирует безопасную функцию приведения во время генерации кода.

  • Отключено: Для несопоставляемого входного значения Simulink генерирует ошибку во время моделирования. Программное обеспечение пропускает функцию безопасного приведения во время генерации кода. В этом случае код более эффективен. Однако код может быть более уязвимым для ошибок времени выполнения.

Безопасная литейная функция в сгенерированном коде

В этом примере показано функционирование безопасного литья int32_T ET08_safe_cast_to_BasicColors для перечисления 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;
}
С помощью этой функции значение по умолчанию перечисляемого типа используется, если входное значение не соответствует одному из базовых значений перечисляемого типа.

Если параметр Saturate on integer overflow блока отключен, эта функция не появляется в сгенерированном коде.

Ограничения перечисляемого типа

  • Созданный код не поддерживает ведение журнала перечисляемых данных.

См. также

| |

Связанные темы