Сконфигурируйте данные сигнала для генерации кода C

Данные сигнала состоят из переменных, которые хранят промежуточные результаты в глобальной памяти, когда сгенерированный алгоритмический код вычисляет значения сигналов выхода блока от входных сигналов блока, исключая сигналы, которые соединяются с корневыми блоками Inport и Outport. Данные о сигнале не являются сигнальными линиями в диаграмму модели. Для примера в этих случаях сигнальная линия не имеет представления данных в сгенерированном коде:

  • Передает порт вызова функции

  • Выход из блока сообщений, такого как блок Send

  • Пересекает контуры подсистемы без вычислительных блоков между

Когда вы конфигурируете модель для генерации кода, вы выбираете входные и выходные сигналы блоков, чтобы сделать доступными в сгенерированном коде. Для примера сконфигурируйте данные сигнала так:

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

  • Минимизируйте объем данных, которые хранятся в памяти.

  • Управляйте, где генератор кода помещает данные сигнала в память.

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

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

Генератор кода проверяет согласованность строения сигнальной линии. Например, генератор кода проверяет, что строение сигнальной линии, поступающей в подсистему, соответствует строению сигнальной линии, которая выходит из соответствующего входного порта подсистемы.

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

Выберите опции строения кода для сигналов

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

  • Какие сигналы сделать доступными в сгенерированном коде

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

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

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

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

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

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

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

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

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

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

  • Включите volatile type qualifier в определениях и объявлениях глобальных переменных. Требуется Embedded Coder. Смотрите Protect Global Data with const and volatile Type Qualifiers (Embedded Coder).

  • Поместите данные сигнала в определенную область памяти. Требуется Embedded Coder. Смотрите Control Data and Function Placement in Memory by Inserting Pragmas (Embedded Coder).

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

Требования к сигналу, например, к модели rtwdemo_configrpinterface являются:

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

  • Представление сигналов как отдельных глобальных переменных.

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

Установите представление сигналов по умолчанию в сгенерированном коде как глобальные переменные, которые имеют static type qualifier. Затем вы конфигурируете выходные сигналы двух блоков интерполяционной таблицы, чтобы использовать класс памяти по умолчанию и уникальные идентификаторы кода, которые включают необходимый префикс dout_.

Добавьте сигналы к отображениям кода модели

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

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

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

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

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

  4. В редакторе Отображения перейдите на вкладку Signals/States. Сигналы не перечислены.

  5. Добавьте сигналы к отображениям кода. Для выходного сигнала блоков интерполяционной таблицы Table1 и Table2:

    1. В модели выберите сигнал.

    2. Пауза на многоточии, которая появляется выше или ниже сигнальной линии, чтобы открыть панель действий. Нажмите кнопку Add Signal (добавить сигнал).

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

    В редакторе Отображения узел Signals расширяется и перечисляет два добавленных сигнала.

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

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

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

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

В этом примере показано, как использовать Code Mappings editor, чтобы задать класс памяти по умолчанию для сигналов в модели rtwdemo_configrpinterface на ExportedGlobal. С помощью этой настройки класса памяти генератор кода представляет данные сигнала в сгенерированном коде как глобальные переменные.

  1. Если вы еще не сделали этого, добавьте сигналы к отображениям кода модели, как описано в Add Signals to Model Code Mappings.

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

  3. В редакторе Отображения в разделе Signals выберите 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. Сохраните модель.

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

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

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

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

  • Использует несколько сигналов.

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

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

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

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

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

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

  3. В редакторе Code Mappings выберите выходные сигналы для блоков Table1 и Table2. Установите класс памяти равным Model default: ExportedGlobal.

  4. Сконфигурируйте идентификатор кода для выходных сигналов для двух блоков интерполяционной таблицы с именами, которые включают префикс dout_. В редакторе Отображения выберите сигнал Table1:1. В Property Inspector разверните узел Code. Установите свойство класса памяти Identifier равным dout_Table1. Для Table2:1 сигналов, установите Identifier равным 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. Property Inspector shows Identifier property for signal Table2:1 set to dout_Table2.

  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 Code выберите Code Interface > Individual Element Code Mappings.

  2. В редакторе Отображения перейдите на вкладку Signals/States.

  3. Для каждого сигнала, который вы хотите удалить:

    1. В модели выберите сигнал.

    2. Пауза на многоточии, которая появляется выше или ниже сигнальной линии, чтобы открыть панель действий. Нажмите кнопку «Удалить сигнал».

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

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

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

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

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

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

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

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

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

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

    getDataDefault(cm,'InternalData','StorageClass')
    
    ans =
    
        'ExportedGlobal'
    
  5. Получите указатели на выходные порты для блоков интерполяционной таблицы 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. Добавьте выходные сигналы блоков интерполяционной таблицы к отображениям кода модели.

    addSignal(cm,[lut1D_outPort,lut2D_outPort]);
    
  7. Примените строение по умолчанию для сигналов к выходу сигналу блоков интерполяционной таблицы.

    По умолчанию 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;
    }
    

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

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

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

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

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

См. также

|

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте