Эта тема описывает, как реализовать асинхронные блоки для использования с вашим целевым RTOS, с помощью Async Interrupt и блоков Task Sync как начальная точка. блоки Rate Transition независимы от цели, таким образом, вы не должны разрабатывать настроенные блоки перехода уровня.
Примечание
Методы интегрирования операционной системы, которые продемонстрированы в этом использовании раздела блоки, которые находятся в библиотеке блоков Шаблонов Прерывания. Блоки в той библиотеке обеспечивают примеры начальной точки, чтобы помочь вам разработать пользовательские блоки для целевого окружения.
Можно настроить асинхронные библиотечные блоки путем изменения реализации блока. Эти файлы
Базовый файл MEX S-функции блока
Файлы TLC, что генерация кода системы управления блока
Кроме того, необходимо изменить маски блока, чтобы удалить ссылки, характерные для примера RTOS (VxWorks®) и включить параметры, требуемые вашим целевым RTOS.
Реализация пользовательского блока является усовершенствованной темой, требуя знакомства с Simulink® Формат S-функции MEX и API, и с Компилятором выходного языка (TLC). Эти темы затронуты в следующих документах:
Темы Simulink, Что такое S-функция?, S-функции Использования в Моделях, Как работа S-функций и S-функции Реализации описывают S-функции MEX и API S-функции в целом.
S-функции Встраивания, Встройте S-функции MEX C, и S-функции и Генерация кода описывают, как создать реализацию блока TLC для использования в генерации кода.
Следующие разделы обсуждают C/C++ и реализации TLC асинхронных библиотечных блоков, включая необходимый SimStruct
макросы и функции в асинхронной вспомогательной библиотеке TLC (asynclib.tlc
).
Исходные файлы для блока Async Interrupt расположены в
открытый:matlabroot
/rtw/c/tornado/devices
vxinterrupt1.c
: Исходный код файла MEX на C, для использования в настройке и симуляции
vxinterrupt1.tlc
: Реализация TLC, для использования в генерации кода
asynclib.tlc
: библиотека функций поддержки TLC, вызванных реализацией TLC блока. Вызовы библиотеки получены в итоге в asynclib.tlc Вспомогательной библиотеке.
Большая часть кода в vxinterrupt1.c
выполняет обычные функции, которые не связаны с асинхронной поддержкой (например, получая и подтверждая параметры от маски блока, отмечая параметры ненастраиваемые, и передающие данные о параметре к
файл).model
.rtw
mdlInitializeSizes
функционируйте использует специальный SimStruct
макросы и SS_OPTIONS
настройки, которые требуются для асинхронных блоков, аналогичных описанному ниже.
Обратите внимание на то, что следующие макросы не могут быть названы прежде ssSetOutputPortWidth
называется:
ssSetTimeSource
ssSetAsyncTimerAttributes
ssSetAsyncTimerResolutionEl
ssSetAsyncTimerDataType
ssSetAsyncTimerDataTypeEl
ssSetAsyncTaskPriorities
ssSetAsyncTaskPrioritiesEl
Если одни из вышеупомянутых макросов называются прежде ssSetOutputPortWidth
, следующее сообщение об ошибке появляется:
SL_SfcnMustSpecifyPortWidthBfCallSomeMacro { S-function '%s' in '%<BLOCKFULLPATH>' must set output port %d width using ssSetOutputPortWidth before calling macro %s }
ssSetAsyncTimerAttributes. ssSetAsyncTimerAttributes
объявляет, что блок требует таймера и устанавливает разрешение таймера, как задано для параметров блоков Timer resolution (seconds).
Прототип функции
ssSetAsyncTimerAttributes(SimStruct *S, double res)
где
S является указателем Simstruct.
Параметр Timer resolution (seconds) устанавливается на res
.
Следующая выборка кода показывает вызов ssSetAsyncTimerAttributes.
/* Setup Async Timer attributes */ ssSetAsyncTimerAttributes(S,mxGetPr(TICK_RES)[0]);
ssSetAsyncTaskPriorities. ssSetAsyncTaskPriorities
устанавливает приоритет задач Simulink для блоков, выполняющихся на каждом уровне прерывания, как задано для параметров блоков Simulink task priority.
Прототип функции
ssSetAsyncTaskPriorities(SimStruct *S, int numISRs, int *priorityArray)
где
S
SimStruct
указатель.
numISRs
количество прерываний, заданных для параметров блоков VME interrupt number(s).
priorityarray
целочисленный массив, содержащий номера прерывания, заданные для параметров блоков VME interrupt number(s).
Следующая выборка кода показывает вызов ssSetAsyncTaskPriorities
:
/* Setup Async Task Priorities */ priorityArray = malloc(numISRs*sizeof(int_T)); for (i=0; i<numISRs; i++) { priorityArray[i] = (int_T)(mxGetPr(ISR_PRIORITIES)[i]); } ssSetAsyncTaskPriorities(S, numISRs, priorityArray); free(priorityArray); priorityArray = NULL; }
Настройки SS_OPTION. Выборка кода ниже показов SS_OPTION
настройки для vxinterrupt1.c
. SS_OPTION_ASYNCHRONOUS_INTERRUPT
должен использоваться, когда подсистема вызова функции присоединена к прерыванию. Для получения дополнительной информации см. документацию для SS_OPTION
и SS_OPTION_ASYNCHRONOUS
в
.matlabroot
/simulink/include/simstruc.h
ssSetOptions( S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | SS_OPTION_ASYNCHRONOUS_INTERRUPT |
Если S-функция задает SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME
опция и наследовала шаг расчета Inf
, генератор кода определяет, как произвести код для блока на основе того, является ли блок инвариантным. Блок является инвариантным, если его сигналы порта являются инвариантными. Сигнал является инвариантным, если он имеет постоянное значение во время целой симуляции. Если вы задаете шаг расчета блока Constant, не принимайте, что сигналы порта являются инвариантными. Для получения дополнительной информации видят Встроенные Инвариантные Сигналы. Если блок не является инвариантным, генератор кода производит код только в инициализировать функции точки входа. Если блок является инвариантным, генератор кода не производит код для блока.
В этом разделе рассматриваются каждую функцию vxinterrupt1.tlc
, с акцентом на целевые функции, которые необходимо будет изменить, чтобы сгенерировать код для целевого RTOS.
Сгенерируйте #include директивы. vxinterrupt1.tlc
начинается с оператора
%include "vxlib.tlc"
vxlib.tlc
целевой файл, который генерирует директивы, чтобы включать заголовочные файлы для примера RTOS (VxWorks). Необходимо заменить это на файл, который генерирует, включает для целевого RTOS.
Функция BlockInstanceSetup. Поскольку каждый соединил выход блока Async Interrupt, BlockInstanceSetup
задает имя функции для соответствующего ISR в сгенерированном коде. Имена функций имеют форму
isr_num_vec_offset
где
номер ISR, заданный для параметров блоков VME interrupt number(s) и num
смещение таблицы прерываний, заданное параметрами блоков VME interrupt vector offset(s).offset
В пользовательской реализации это соглашение о присвоении имен является дополнительным.
Имена функций кэшируются для использования Outputs
функция, которая генерирует фактический код ISR.
Выходная функция. Outputs
выполняет итерации по связанным выходным параметрам блока Async Interrupt. ISR сгенерирован для каждого такого выхода.
Код ISR кэшируется в "Functions"
раздел сгенерированного кода. Прежде, чем сгенерировать ISR, Outputs
делает следующее:
Генерирует вызов нисходящего блока (кэшируемый во временном буфере).
Определяет, должен ли ISR быть заблокирован или не (как задано параметрами блоков Preemption Flag(s)).
Определяет, является ли блок, соединенный с блоком Async Interrupt, блоком Task Sync. (Эта информация получена при помощи asynclib
вызовы LibGetFcnCallBlock
и LibGetBlockAttribute
.) Если так,
Флаг вытеснения для ISR должен быть установлен в 1
. Ошибка заканчивается в противном случае.
RTOS (VxWorks) вызовы, чтобы сохранить и восстановить контекст с плавающей точкой сгенерированы, если пользователь не сконфигурировал модель для генерации кода только для целого числа.
При генерации кода ISR, Outputs
вызывает asynclib
функция LibNeedAsyncCounter
определить, требуется ли таймер связанной подсистемой. Если так, и если источник времени собирается быть SS_TIMESOURCE_SELF
ssSetTimeSource
, LibSetAsyncCounter
называется, чтобы сгенерировать RTOS (VxWorks) tickGet
вызов функции и обновление счетчик. В вашей реализации необходимо сгенерировать или эквивалентный вызов целевого RTOS или сгенерировать код, чтобы считать регистр таймера на целевом компьютере.
Запустите функцию. Start
функция генерирует необходимый RTOS (VxWorks) вызовы (int_connect
и sysInt_Enable
) соединить и включить каждый ISR. Необходимо заменить это на вызовы целевого RTOS.
Оконечная функция. Terminate
функция генерирует вызов sysIntDisable
отключить каждый ISR. Необходимо заменить это на вызовы целевого RTOS.
Исходные файлы для блока Task Sync расположены в
открытый. Ониmatlabroot
/rtw/c/tornado/devices
vxtask1.cpp
: Исходный код файла MEX, для использования в настройке и симуляции.
vxtask1.tlc
: Реализация TLC, для использования в генерации кода.
asynclib.tlc
: библиотека функций поддержки TLC, вызванных реализацией TLC блока. Вызовы библиотеки получены в итоге в asynclib.tlc Вспомогательной библиотеке.
Как блок Async Interrupt, блок Task Sync настраивает таймер, в этом случае с фиксированным разрешением. Приоритет задачи, сопоставленной с блоком, получен из параметров блоков Simulink task priority. SS_OPTION
настройки совпадают с используемыми для блока Async Interrupt.
ssSetAsyncTimerAttributes(S, 0.01); priority = (int_T) (*(mxGetPr(PRIORITY))); ssSetAsyncTaskPriorities(S,1,&priority); ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_ASYNCHRONOUS | SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME | }
Сгенерируйте #include директивы. vxtask1.tlc
начинается с оператора
%include "vxlib.tlc"
vxlib.tlc
целевой файл, который генерирует директивы, чтобы включать заголовочные файлы для примера RTOS (VxWorks). Необходимо заменить это на файл, который генерирует, включает для целевого RTOS.
Функция BlockInstanceSetup. BlockInstanceSetup
функция выводит имя задачи, имя блока и другие идентификаторы, используемые позже в генерации кода. Это также проверяет на и предупреждает о несвязанных условиях блока и генерирует объявление устройства хранения данных для семафора (stopSem
) это используется в случае условий переполнения прерывания.
Запустите функцию. Start
функция генерирует необходимый RTOS (VxWorks) вызовы, чтобы задать устройство хранения данных для семафора, который используется в управлении задачей, порожденной блоком Task Sync. В зависимости от значения CodeFormat
Переменная TLC цели, или статическое объявление устройства хранения данных или вызов динамического выделения памяти сгенерированы. Эта функция также создает семафор (semBCreate
) и порождает задачу RTOS (taskSpawn
). Необходимо заменить их на вызовы целевого RTOS.
Выходная функция. Outputs
функция генерирует пример RTOS (VxWorks) задача, которая ожидает семафора. Когда это получает семафор, это обновляет таймер метки деления блока и вызывает нисходящий код подсистемы, как описано в Икре, и Синхронизируйте Выполнение Задачи RTOS. Outputs
также генерирует код (названный от уровня прерывания), который предоставляет семафор.
Оконечная функция. Terminate
функция генерирует пример RTOS (VxWorks) вызов taskDelete
закончить выполнение задачи, порожденной блоком. Необходимо заменить это на вызовы целевого RTOS.
Обратите внимание также на это, если целевой RTOS динамически выделил память, сопоставленную с задачей, Terminate
функция должна освободить память.
asynclib.tlc
библиотека функций TLC, которые поддерживают реализацию асинхронных блоков. Некоторые функции специально предназначены для использования в асинхронных блоках. Например, LibSetAsyncCounter
генерирует вызов, чтобы обновить таймер для асинхронного блока. Другие функции являются утилитами, которые возвращают информацию, запрошенную асинхронными блоками (например, информацию о связанных подсистемах вызова функции).
Следующая таблица обобщает общедоступные вызовы в библиотеке. Для получения дополнительной информации см. исходный код библиотеки и vxinterrupt1.tlc
и vxtask1.tlc
файлы, которые вызывают библиотечные функции.
Сводные данные asynclib.tlc Библиотечных функций
Функция | Описание |
---|---|
| Для использования встроенными S-функциями с вызовом функции выходные параметры. Генерирует код, чтобы выполнить подсистему вызова функции. |
| Возвращает значение поля от записи блока. |
| Учитывая Блок s-function и индекс вызова, возвращает запись блока для нисходящего блока подсистемы вызова функции. |
| Обеспечивает доступ к счетчику времени восходящей асинхронной задачи. |
| Обеспечивает доступ к высокому слову счетчика времени восходящей асинхронной задачи. |
| Определяет, нужна ли асинхронная задача в счетчике и управляет его собственным таймером. |
| Если блок вызова требует асинхронного счетчика, возвращает |
| Возвращает код, который устанавливает |
| Генерирует код, чтобы установить значение деления асинхронного счетчика блока. |
| Генерирует код, чтобы установить значение деления высокого слова асинхронного счетчика блока |