Сконфигурируйте блоки Inport корневого уровня для генерации кода C

Чтобы использовать код, который вы генерируете из модели, вы вызываете сгенерированные функции точки входа. Вызывающее окружение и сгенерированные функции обмениваются входными и выходными данными, для примера, как глобальные переменные или аргументы функции. Блоки Inport корневого уровня (inports) составляют входные данные интерфейса. Чтобы интегрировать и развернуть сгенерированный код в приложениях, можно настроить, как генератор кода производит код интерфейса, включая то, как объявляются и обрабатываются входные данные. Индивидуальные настройки могут:

  • Минимизируйте изменения, которые вы должны внести в существующий код.

  • Сгенерируйте стабильные интерфейсы, которые не изменяются или минимально изменяются, когда вы вносите изменения в свою модель.

  • Сгенерируйте код, который обменивается данными более эффективно (для примера, с помощью указателей и аргументов pass-by-reference для нескалярных данных).

Enable и Trigger блоки (входные порты вызова функции) также загружают данные в систему извне системы. С точки зрения генерации кода эти элементы моделирования являются экспортированными функциями. Для экспортированной функции генератор кода производит функцию точки входа, которую можно сконфигурировать. Смотрите Configure C Code Generation для моделирования функций точки входа.

Для генерации кода примеры показывают, как настроить интерфейс inport для модели rtwdemo_configinterface . Можно сконфигурировать отображения кода с помощью Code Mappings editor или отображений кода API (coder.mapping.api.CodeMapping).

Выберите опции индивидуальной настройки для интерфейса Inport

По умолчанию входные порты корневого уровня в модели появляются в сгенерированном коде как поля глобальных данных структуры с именем model_ExtU. На основе требований к интерфейсам кода решите, настраивать ли генерацию входных данных корневого уровня. Если вы не конфигурируете индивидуальных настроек, генератор кода определяет, устранять или изменять представление входных портов в сгенерированном коде в целях оптимизации. Если вы конфигурируете индивидуальные настройки, решите:

  • Настройка ли строения по умолчанию

    Если модель включает значительное количество (для примера, более 10) входных портов корневого уровня, более эффективно сконфигурировать входные порты с настройкой по умолчанию, а затем переопределить эту настройку для особых случаев. Если модель включает несколько входных портов корневого уровня, которые имеют уникальные требования к источнику, именованию или размещению, рассмотрите настройку входных портов отдельно.

  • Как объявить и обработать входные данные корневого уровня в сгенерированном интерфейсе

    • Как отдельные глобальные переменные

    • Чтобы считать входные данные из глобальных переменных, определенных во внешнем коде

    • Для ссылочных моделей входных портов как глобальных переменных (void-void)

    • Как вызовы для доступа к функциям. Требуется Embedded Coder®

    • Как аргументы функции точки входа. Требуется Embedded Coder

    Для получения дополнительной информации об этих опциях смотрите Управляющие данные и Интерфейс функции в Сгенерированном коде.

Другие факторы включают в себя вопрос о том, следует ли:

Список требований к интерфейсам, релевантных для входных портов с соответствующими классами памяти и свойствами класса памяти, см. в разделе Выбор классе памяти для контроля представления данных в сгенерированном коде.

Для примера модели rtwdemo_configinterface, требования к интерфейсам входных портов:

  • Используйте определение типа проекта DBL_FLOAT определено в заголовочном файле exDblFloat.h.

  • Получите данные для входных In1 из файла заголовка exInDataMem.h. Данные используются для вычисления значения, которое хранится в памяти, а затем используется в условии if-else кода, сгенерированного для блока Switch.

  • Получите элементы данных для входных портов In2, In3, и In4 из файла заголовка exInDataLut.h. Данные используются в интерполяционных таблицах Table1 и Table2.

  • Переменные, представляющие входные порты в сгенерированном коде, должны быть именованы input1, input2, input3, и input4.

В данном примере сконфигурируйте входные порты в rtwdemo_configinterface для соответствия этим требованиям генерации кода.

Настройте настройки генерации кода по умолчанию для входных портов корневого уровня

Настройка генерации кода по умолчанию для входных портов корневого уровня может уменьшить усилия по подготовке модели к генерации кода, особенно если модель имеет значительное количество входных портов. Выберите настройки строения один раз, и генератор кода применяет эти настройки к входным портам через модель. Simulink® сохраняет строение по умолчанию как часть модели.

Рассмотрите настройку настроек генерации кода по умолчанию для inports корневого уровня модели, если ваша модель использует несколько inports корневого уровня, которые не имеют уникальных требований или использует общий словарь Embedded Coder.

В этом примере показано, как использовать Code Mappings editor для конфигурации настроек по умолчанию для входных портов корневого уровня для rtwdemo_configinterface модели. Укажите внешний файл заголовка, который объявляет входные данные. Три из четырех корневых входных портов считывают вход из переменных, объявленных в заголовочном файле exInDataLut.h. Установите этот файл заголовка в качестве входного источника по умолчанию для входных портов.

  1. Откройте пример модели rtwdemo_configinterface. Сохраните копию модели в месте с возможностью записи.

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

  2. Откройте приложение Embedded Coder.

  3. На вкладке C Code выберите Code Interface > Default Code Mappings.

  4. В редакторе Отображения в разделе Inports and Outports выберите Inports категории. Установите класс памяти по умолчанию равным ImportFromFile.

  5. В Property Inspector установите значение файла заголовка на exInDataLut.h.

    Code Mappings editor with Data Defaults tab selected, Inports and Outports tree node expanded, and storage class for Inports set to ImportFromFile. Property Inspector with HeaderFile property set to exInDataLut.h

  6. Сохраните модель.

Настройте настройки генерации кода для отдельных входных портов корневого уровня

Можно сконфигурировать отдельные входные порты корневого уровня для генерации кода. Например, если модель имеет два входных порта корневого уровня, которые имеют уникальные требования к генерации кода, сконфигурируйте входные порты индивидуально. Или, если вы конфигурируете настройки по умолчанию для inports, сконфигурируйте отдельные inports, чтобы использовать настройки по умолчанию или уникальные настройки.

Если ваша модель соответствует хотя бы одному из следующих критериев, рассмотрите настройку настроек генерации кода для входных портов корневого уровня индивидуально:

  • Использует несколько входных портов, имеющих уникальные требования.

  • Использует немного входных портов.

  • Имеет строение по умолчанию для входных портов, и вам нужно переопределить строение для некоторых определенных входных портов.

В этом примере показано, как использовать редактор Отображения для переопределения строения генерации кода по умолчанию для одного из входных портов в модели rtwdemo_configinterface. В предыдущем примере класс памяти по умолчанию для inports устанавливается равным ImportFromFile. Модель требует, чтобы входной порт In1 считайте входные данные из глобальной переменной вместо указателя на глобальную переменную.

В примере также показано, как сконфигурировать идентификаторы, которые генератор кода использует для именования четырех входных портов в сгенерированном коде. Можно задать идентификаторы генерации кода, для примера для интегрирования, не меняя проект модели.

  1. Если вы еще не сделали этого, выполните действия в разделе «Настройка настроек генерации кода по умолчанию для входных портов корневого уровня».

  2. В редакторе Отображения перейдите на вкладку Inports. Редактор перечисляет имена блоков Inport и элементов шины, которые находятся в модели. Если порт разрешается к объекту сигнала, справа от имени элемента появляется значок разрешения к объекту сигнала. Класс памяти для каждого входного порта установлен на Auto, что означает, что генератор кода может исключить или изменить представление соответствующего кода в целях оптимизации. Если оптимизация невозможна, генератор кода применяет строение модели по умолчанию. В данном примере строение модели по умолчанию задаёт класс памяти ImportedFromFile.

    • Чтобы избежать оптимизации и заставить генератор кода использовать строение по умолчанию, установите класс памяти равным Model default.

    • Чтобы переопределить строение по умолчанию, задайте класс памяти, соответствующий требованиям генерации кода для этого входного порта.

  3. Сконфигурируйте генератор кода, чтобы применить настройку класса памяти по умолчанию к входным портам In2, In3, и In4. Выберите строки для трех входных портов. Затем для одного из выбранных входных портов установите класс памяти равным Model default: ImportFromFile.

    Code Mappings editor with Inports tab selected, signals In2, In3, and In4 selected, and storage class being set to Model default: ImportFromFile.

    Класс памяти для трех выбранных входных портов изменяется на Model default: ImportFromFile.

  4. Для входных In1, переопределите настройку класса памяти по умолчанию. Установите класс памяти равным ImportFromFile. В Property Inspector установите Header File равным exInDataMem.h.

    Code Mappings editor with Inports tab selected, signal In1 selected, and storage class being set to ImportFromFile. Property Inspector with HeaderFile property set to exInDataMem.h.

  5. Сконфигурируйте идентификаторы кода для входных портов так, чтобы имена аргумента интерфейса в сгенерированном коде совпадали с именами интерфейсов во внешних файлах заголовка и определения. В редакторе Отображения выберите строку для каждого входного порта. В Property Inspector установите свойство Identifier на эти значения.

    InportИдентификатор кода
    In1input1
    In2input2
    In3input3
    In4input4
  6. Сохраните модель.

  7. Сгенерируйте и просмотрите код. Для примера, в rtwdemo_configinterface.c найти, где переменные input1, input2, input3, и input4 используются в функции точки входа шага.

    void rtwdemo_configinterface_step(void)
    {
      mode = ((input1 > rtwdemo_configinterface_UPPER) || (input1 <
               rtwdemo_configinterface_LOWER));
    
      dout_Table1 = look1_binlc(input2, ((const MYTYPE *)&(Table1.BP[0])), ((
        const MYTYPE *)&(Table1.Table[0])), 10U);
    .
    .
    .
      dout_Table2 = look2_binlc(input3, input4, ((const MYTYPE *)&(mp_Table2.BP1[0])),
        ((const MYTYPE *)&(mp_Table2.BP2[0])), ((const MYTYPE *)&(mp_Table2.Table[0])),
        ((const uint32_T *)&(rtwdemo_configi_Table2_maxIndex[0])), 3U);
    
      dstate_X = dout_Table2;
    }
    

Настройте настройки генерации кода для входных портов корневого уровня программно

Чтобы автоматизировать строение входных портов корневого уровня для генерации кода, используйте интерфейс программирования для отображений кода. Например, при создании пользовательских библиотек блоков или части тестового окружения приложения используйте интерфейс программирования для автоматизации строения данных.

В этом примере показано, как использовать интерфейс программирования для настройки параметров по умолчанию для входных портов корневого уровня для rtwdemo_configinterface модели. Укажите внешний файл заголовка, который объявляет входные данные. Три из четырех входных портов корневого уровня считывают входы из переменных, объявленных в заголовочном файле exInDataLut.h. Этот файл устанавливается в качестве файла заголовка по умолчанию. Затем вы переопределяете строение генерации кода по умолчанию для In1, что требует, чтобы входные данные считывались из заголовочного файла exInDataMem.h.

В сложение вы конфигурируете идентификаторы кода для входных портов так, чтобы имена глобальных переменных в сгенерированном коде совпадали с именами переменных, определенными во внешнем файле.

  1. Откройте пример модели.

    open_system('rtwdemo_configinterface')
    
  2. Создайте объект cm вызовом функции coder.mapping.api.get. Объект хранит данные и строение генерации кода функции для модели rtwdemo_configinterface.

    cm = coder.mapping.api.get('rtwdemo_configinterface');
  3. Сконфигурируйте настройки по умолчанию для входных портов путем вызова функции setDataDefault. Для аргументов задайте следующие значения:

    • Объект, возвращенный coder.mapping.api.get

    • Inports для категории по умолчанию

    • Имя свойства StorageClass со значением свойства ImportFromFile

    • Имя свойства HeaderFile со значением свойства exInDataLut.h, имя внешнего файла, содержащего входные данные

    setDataDefault(cm,'Inports','StorageClass','ImportFromFile','HeaderFile','exInDataLut.h')
  4. Проверьте строение по умолчанию для входных портов. Выполните два вызова getDataDefault который задает объект, возвращенный coder.mapping.api.get и Inports категорий. В первом вызове задайте третий аргумент как свойство StorageClass. Во втором вызове для третьего аргумента задайте HeaderFile.

    getDataDefault(cm,'Inports','StorageClass')
    
    ans =
    
        'ImportFromFile'
    
    getDataDefault(cm,'Inports','HeaderFile')
    
    ans =
    
        'exInDataLut.h'
    
  5. Переопределите строение входного порта по умолчанию для входного In1. Требования к этому входному порту отличаются от требований к другим трем входным портам.

    По умолчанию Simulink устанавливает класс памяти для отдельных входных портов равным Auto. Когда класс памяти Auto, генератор кода:

    • Определяет, следует ли исключить данные из сгенерированного кода в целях оптимизации.

    • При сохранении данных определяет, как эффективно представлять данные в сгенерированном коде с учетом настроек строения по умолчанию.

    Чтобы управлять классом памяти и строением файла заголовка для inport, сконфигурируйте настройки для inport с функцией setInport. Сконфигурируйте код, сгенерированный для inport In1 для чтения входных данных из глобальных переменных, определенных во внешнем заголовочном файле exInDataMem.h, как указано в требованиях. Выполните два вызова для функционирования setInport который задает объект, возвращенный coder.mapping.api.get и Inport блок с именем In1. В первом вызове также задайте имя свойства StorageClass и значение свойства ImportFromFile. Во втором вызове задайте имя свойства HeaderFile и значение свойства exInDataMem.h.

    setInport(cm,'In1','StorageClass','ImportFromFile')
    setInport(cm,'In1','HeaderFile','exInDataMem.h')
  6. Проверьте свои строения на наличие In1 вызовом функции getInport.

    getInport(cm,'In1','StorageClass')
    
    ans =
    
        'ImportFromFile'
    
    getInport(cm,'In1','HeaderFile')
    
    ans =
    
        'exInDataMem.h'
  7. Сконфигурируйте генератор кода, чтобы применить настройки входного порта по умолчанию к входным портам In2, In3, и In4. Для каждого входного порта вызовите функцию setInport. Задайте объект, возвращенный coder.mapping.api.get, имя Inport блока, имя свойства StorageClass, и значение свойства Model default.

    setInport(cm,'In2','StorageClass','Model default')
    setInport(cm,'In3','StorageClass','Model default')
    setInport(cm,'In4','StorageClass','Model default')
    
  8. Проверьте изменения строения для входных портов In2, In3, и In4 с вызовами функции getInport.

    getInport(cm,'In2','StorageClass')
    
    ans =
    
        'Model default'
    
    getInport(cm,'In3','StorageClass')
    
    ans =
    
        'Model default'
    
    
    getInport(cm,'In4','StorageClass')
    
    ans =
    
        'Model default'
  9. Сконфигурируйте идентификаторы кода для входных портов так, чтобы глобальные переменные, представляющие входные порты в сгенерированном коде, совпадали с именами переменных во внешнем файле определения. Для каждого входного порта вызовите функцию setInport. Задайте объект, возвращенный coder.mapping.api.get, имя Inport блока, имя свойства Identifier, и одно из этих значений свойств.

    InportИдентификатор кода
    In1input1
    In2input2
    In3input3
    In4input4
    setInport(cm,'In1','Identifier','input1');
    setInport(cm,'In2','Identifier','input2');
    setInport(cm,'In3','Identifier','input3');
    setInport(cm,'In4','Identifier','input4');
    
  10. Проверьте свои изменения строения для входных портов при помощи вызовов для функционирования getInport.

    getInport(cm,'In1','Identifier')
    
    ans =
    
        'input1'
    
    getInport(cm,'In2','Identifier')
    
    ans =
    
        'input2'
    
    getInport(cm,'In3','Identifier')
    
    ans =
    
        'input3'
    
    
    getInport(cm,'In4','Identifier')
    
    ans =
    
        'input4'
    
  11. Сохраните модель.

  12. Сгенерируйте и просмотрите код. Для примера, в rtwdemo_configinterface.c найти, где переменные input1, input2, input3, и input4 используются в функции точки входа шага.

    void rtwdemo_configinterface_step(void)
    {
      mode = ((input1 > rtwdemo_configinterface_UPPER) || (input1 <
               rtwdemo_configinterface_LOWER));
    
      dout_Table1 = look1_binlc(input2, ((const MYTYPE *)&(Table1.BP[0])), ((
        const MYTYPE *)&(Table1.Table[0])), 10U);
    .
    .
    .
      dout_Table2 = look2_binlc(input3, input4, ((const MYTYPE *)&(mp_Table2.BP1[0])),
        ((const MYTYPE *)&(mp_Table2.BP2[0])), ((const MYTYPE *)&(mp_Table2.Table[0])),
        ((const uint32_T *)&(rtwdemo_configi_Table2_maxIndex[0])), 3U);
    
      dstate_X = dout_Table2;
    }
    

Выберите Класс памяти и Класс памяти свойства для входных портов корневого уровня

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

ТребованияКласс памяти
Включите оптимизацию, потенциально создавая более эффективный код.Авто (только для отдельных отображений)
Для элементов данных, которые не могут быть оптимизированы, представьте данные как поле стандартной структуры данных.По умолчанию (только для отображения по умолчанию)
Предотвратите устранение оптимизации системы хранения данных для элемента данных и используйте отображение по умолчанию для категории элемента данных.Модель по умолчанию (только для отдельных отображений), Dictionary Default (Только отдельные отображения)
Сгенерируйте структуру, которая хранит логические данные в именованных битовых полях.Битовое поле (только для отдельных отображений)
Сгенерируйте глобальное определение переменной и объявление, которые имеют volatile type qualifier.Volatile (См. Const, Volatile и ConstVolatile)
Сгенерируйте глобальное определение переменной и объявление.ExportedGlobal
Сгенерируйте определение глобальной переменной и объявление в указанный файл.ExportToFile
Сгенерируйте код, который взаимодействует с данными, вызывая пользовательские функции доступа.GetSet
Сгенерируйте код, который читается и записывается в глобальную переменную или глобальный указатель переменной, заданный вашим внешним кодом.ImportedExtern, ImportedExternPointer
Считайте входные данные для входного порта из указанного внешнего файла заголовка.ImportFromFile
Сгенерируйте переменные, которые являются локальными по отношению к функциям.Локализуемый
Сгенерируйте глобальную структуру, которая имеет имя, которое можно задать.Struct (только для отдельных отображений)

Список доступных классов памяти может включать другие специфичные для проекта классы памяти, определенные в словаре Embedded Coder Dictionary. Если у вас есть особые требования, не удовлетворяющие перечисленным классам памяти, и вы имеете программное обеспечение Embedded Coder, можно задать класс памяти. Смотрите раздел «Определение классов памяти, разделов памяти и шаблонов функций» для программной архитектуры.

Для отдельного входного порта используйте свойство Identifier класса памяти, чтобы сконфигурировать имя для переменной, представляющей входной порт в сгенерированном коде. С помощью Embedded Coder, в зависимости от выбранного класса памяти, можно также сконфигурировать эти свойства.

СвойствоОписаниеКлассы памяти
DefinitionFileИсходный файл определения, который содержит определения для глобальных данных, который считывается входным и внешним кодомExportToFile и Volatile
GetFunctionInport появляется в сгенерированном коде как вызов к заданному get функцияGetSet
HeaderFileИсходный файл заголовка, содержащий объявления для глобальных данных, считываемые входным и внешним кодомExportToFile, GetSet, ImportFromFile, и Volatile
Memory Section(только строение входного порта по умолчанию)Раздел памяти, содержащий данные, считанные входным портомDefault
OwnerГенератор кода помещает определение для входных портов в код, сгенерированный для одной из нескольких моделей в иерархии модели, которая разделяет определения. Необходимо выбрать параметр конфигурации модели Use owner from data object for data definition placement. См. Раздел «Управление размещением определений глобальных данных и объявлений в сгенерированных файлах».ExportToFile и Volatile
PreserveDimensionsГенератор кода сохраняет размерности входных данных, которые представлены в сгенерированном коде как многомерный массив. Вы должны задать Array layout параметра конфигурации модели на Row-major. См. «Сохранение размерностей многомерных массивов в сгенерированном коде».ExportToFile, ImportFromFile, Localizable, и Volatile
SetFunctionInport появляется в сгенерированном коде как вызов к заданному set функция.GetSet
StructNameИмя структуры в сгенерированном коде для inport.BitField и Struct

См. также

|

Похожие темы