Чтобы использовать код, который вы генерируете из модели, вы вызываете сгенерированные функции точки входа. Вызывающее окружение и сгенерированные функции обмениваются входными и выходными данными, для примера, как глобальные переменные или аргументы функции. Блоки Inport корневого уровня (inports) составляют входные данные интерфейса. Чтобы интегрировать и развернуть сгенерированный код в приложениях, можно настроить, как генератор кода производит код интерфейса, включая то, как объявляются и обрабатываются входные данные. Индивидуальные настройки могут:
Минимизируйте изменения, которые вы должны внести в существующий код.
Сгенерируйте стабильные интерфейсы, которые не изменяются или минимально изменяются, когда вы вносите изменения в свою модель.
Сгенерируйте код, который обменивается данными более эффективно (для примера, с помощью указателей и аргументов pass-by-reference для нескалярных данных).
Enable и Trigger блоки (входные порты вызова функции) также загружают данные в систему извне системы. С точки зрения генерации кода эти элементы моделирования являются экспортированными функциями. Для экспортированной функции генератор кода производит функцию точки входа, которую можно сконфигурировать. Смотрите Configure C Code Generation для моделирования функций точки входа.
Для генерации кода примеры показывают, как настроить интерфейс inport для модели rtwdemo_configinterface
. Можно сконфигурировать отображения кода с помощью Code Mappings editor или отображений кода API (coder.mapping.api.CodeMapping
).
По умолчанию входные порты корневого уровня в модели появляются в сгенерированном коде как поля глобальных данных структуры с именем
. На основе требований к интерфейсам кода решите, настраивать ли генерацию входных данных корневого уровня. Если вы не конфигурируете индивидуальных настроек, генератор кода определяет, устранять или изменять представление входных портов в сгенерированном коде в целях оптимизации. Если вы конфигурируете индивидуальные настройки, решите:model
_ExtU
Настройка ли строения по умолчанию
Если модель включает значительное количество (для примера, более 10) входных портов корневого уровня, более эффективно сконфигурировать входные порты с настройкой по умолчанию, а затем переопределить эту настройку для особых случаев. Если модель включает несколько входных портов корневого уровня, которые имеют уникальные требования к источнику, именованию или размещению, рассмотрите настройку входных портов отдельно.
Как объявить и обработать входные данные корневого уровня в сгенерированном интерфейсе
Как отдельные глобальные переменные
Чтобы считать входные данные из глобальных переменных, определенных во внешнем коде
Для ссылочных моделей входных портов как глобальных переменных (void-void
)
Как вызовы для доступа к функциям. Требуется Embedded Coder®
Как аргументы функции точки входа. Требуется Embedded Coder
Для получения дополнительной информации об этих опциях смотрите Управляющие данные и Интерфейс функции в Сгенерированном коде.
Другие факторы включают в себя вопрос о том, следует ли:
Назовите входные порты в сгенерированном коде при помощи меток блоков Inport которые появляются в модели или при помощи уникальных идентификаторов кода.
Включите volatile
type qualifier в определениях и объявлениях глобальных переменных. Требуется Embedded Coder. См. Раздел «Защита глобальных данных с помощью стандартных и энергозависимых классификаторов типов».
Поместите данные, считанные в определенную область памяти. Требуется Embedded Coder. Смотрите Control Data and Function Placement in Memory путем вставки прагм.
Список требований к интерфейсам, релевантных для входных портов с соответствующими классами памяти и свойствами класса памяти, см. в разделе Выбор классе памяти для контроля представления данных в сгенерированном коде.
Для примера модели 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
. Установите этот файл заголовка в качестве входного источника по умолчанию для входных портов.
Откройте пример модели rtwdemo_configinterface
. Сохраните копию модели в месте с возможностью записи.
Откройте приложение Embedded Coder.
На вкладке C Code выберите Code Interface > Default Code Mappings.
В редакторе Отображения в разделе Inports and Outports выберите Inports категории. Установите класс памяти по умолчанию равным ImportFromFile
.
В Property Inspector установите значение файла заголовка на exInDataLut.h
.
Сохраните модель.
Можно сконфигурировать отдельные входные порты корневого уровня для генерации кода. Например, если модель имеет два входных порта корневого уровня, которые имеют уникальные требования к генерации кода, сконфигурируйте входные порты индивидуально. Или, если вы конфигурируете настройки по умолчанию для inports, сконфигурируйте отдельные inports, чтобы использовать настройки по умолчанию или уникальные настройки.
Если ваша модель соответствует хотя бы одному из следующих критериев, рассмотрите настройку настроек генерации кода для входных портов корневого уровня индивидуально:
Использует несколько входных портов, имеющих уникальные требования.
Использует немного входных портов.
Имеет строение по умолчанию для входных портов, и вам нужно переопределить строение для некоторых определенных входных портов.
В этом примере показано, как использовать редактор Отображения для переопределения строения генерации кода по умолчанию для одного из входных портов в модели rtwdemo_configinterface
. В предыдущем примере класс памяти по умолчанию для inports устанавливается равным ImportFromFile
. Модель требует, чтобы входной порт In1
считайте входные данные из глобальной переменной вместо указателя на глобальную переменную.
В примере также показано, как сконфигурировать идентификаторы, которые генератор кода использует для именования четырех входных портов в сгенерированном коде. Можно задать идентификаторы генерации кода, для примера для интегрирования, не меняя проект модели.
Если вы еще не сделали этого, выполните действия в разделе «Настройка настроек генерации кода по умолчанию для входных портов корневого уровня».
В редакторе Отображения перейдите на вкладку Inports. Редактор перечисляет имена блоков Inport и элементов шины, которые находятся в модели. Если порт разрешается к объекту сигнала, справа от имени элемента появляется значок разрешения к объекту сигнала. Класс памяти для каждого входного порта установлен на Auto
, что означает, что генератор кода может исключить или изменить представление соответствующего кода в целях оптимизации. Если оптимизация невозможна, генератор кода применяет строение модели по умолчанию. В данном примере строение модели по умолчанию задаёт класс памяти ImportedFromFile
.
Чтобы избежать оптимизации и заставить генератор кода использовать строение по умолчанию, установите класс памяти равным Model default
.
Чтобы переопределить строение по умолчанию, задайте класс памяти, соответствующий требованиям генерации кода для этого входного порта.
Сконфигурируйте генератор кода, чтобы применить настройку класса памяти по умолчанию к входным портам In2
, In3
, и In4
. Выберите строки для трех входных портов. Затем для одного из выбранных входных портов установите класс памяти равным Model default: ImportFromFile
.
Класс памяти для трех выбранных входных портов изменяется на Model default: ImportFromFile
.
Для входных In1
, переопределите настройку класса памяти по умолчанию. Установите класс памяти равным ImportFromFile
. В Property Inspector установите Header File равным exInDataMem.h
.
Сконфигурируйте идентификаторы кода для входных портов так, чтобы имена аргумента интерфейса в сгенерированном коде совпадали с именами интерфейсов во внешних файлах заголовка и определения. В редакторе Отображения выберите строку для каждого входного порта. В Property Inspector установите свойство Identifier на эти значения.
Inport | Идентификатор кода |
---|---|
In1 | input1 |
In2 | input2 |
In3 | input3 |
In4 | input4 |
Сохраните модель.
Сгенерируйте и просмотрите код. Для примера, в 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
.
В сложение вы конфигурируете идентификаторы кода для входных портов так, чтобы имена глобальных переменных в сгенерированном коде совпадали с именами переменных, определенными во внешнем файле.
Откройте пример модели.
open_system('rtwdemo_configinterface')
Создайте объект cm
вызовом функции coder.mapping.api.get
. Объект хранит данные и строение генерации кода функции для модели rtwdemo_configinterface
.
cm = coder.mapping.api.get('rtwdemo_configinterface');
Сконфигурируйте настройки по умолчанию для входных портов путем вызова функции setDataDefault
. Для аргументов задайте следующие значения:
Объект, возвращенный coder.mapping.api.get
Inports
для категории по умолчанию
Имя свойства StorageClass
со значением свойства ImportFromFile
Имя свойства HeaderFile
со значением свойства exInDataLut.h
, имя внешнего файла, содержащего входные данные
setDataDefault(cm,'Inports','StorageClass','ImportFromFile','HeaderFile','exInDataLut.h')
Проверьте строение по умолчанию для входных портов. Выполните два вызова getDataDefault
который задает объект, возвращенный coder.mapping.api.get
и Inports категорий
. В первом вызове задайте третий аргумент как свойство StorageClass
. Во втором вызове для третьего аргумента задайте HeaderFile
.
getDataDefault(cm,'Inports','StorageClass') ans = 'ImportFromFile' getDataDefault(cm,'Inports','HeaderFile') ans = 'exInDataLut.h'
Переопределите строение входного порта по умолчанию для входного 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')
Проверьте свои строения на наличие In1
вызовом функции getInport
.
getInport(cm,'In1','StorageClass') ans = 'ImportFromFile' getInport(cm,'In1','HeaderFile') ans = 'exInDataMem.h'
Сконфигурируйте генератор кода, чтобы применить настройки входного порта по умолчанию к входным портам 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')
Проверьте изменения строения для входных портов 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'
Сконфигурируйте идентификаторы кода для входных портов так, чтобы глобальные переменные, представляющие входные порты в сгенерированном коде, совпадали с именами переменных во внешнем файле определения. Для каждого входного порта вызовите функцию setInport
. Задайте объект, возвращенный coder.mapping.api.get
, имя Inport блока, имя свойства Identifier
, и одно из этих значений свойств.
Inport | Идентификатор кода |
---|---|
In1 | input1 |
In2 | input2 |
In3 | input3 |
In4 | input4 |
setInport(cm,'In1','Identifier','input1'); setInport(cm,'In2','Identifier','input2'); setInport(cm,'In3','Identifier','input3'); setInport(cm,'In4','Identifier','input4');
Проверьте свои изменения строения для входных портов при помощи вызовов для функционирования 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'
Сохраните модель.
Сгенерируйте и просмотрите код. Для примера, в 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 |
GetFunction | Inport появляется в сгенерированном коде как вызов к заданному 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 |
SetFunction | Inport появляется в сгенерированном коде как вызов к заданному set функция. | GetSet |
StructName | Имя структуры в сгенерированном коде для inport. | BitField и Struct |
Редактор отображений кода | coder.mapping.api.CodeMapping