Эта тема описывает, как реализовать асинхронные блоки для использования с вашим целевым RTOS, с помощью Асинхронных блоков Синхронизации Прерывания и Задачи в качестве отправной точки. Блоки Перехода уровня независимы от цели, таким образом, вы не должны разрабатывать настроенные блоки перехода уровня.
Методы интегрирования операционной системы, которые продемонстрированы в этом разделе, используют один или несколько блоков блоки в библиотеке vxlib1
(Simulink Coder). Эти блоки обеспечивают примеры отправной точки, чтобы помочь вам разработать авторские блоки для своего целевого окружения.
Можно настроить асинхронные блоки библиотеки путем изменения реализации блока. Эти файлы
Базовый файл MEX S-функции блока
Файлы TLC, что генерация кода системы управления блока
Кроме того, необходимо изменить маски блока, чтобы удалить ссылки, характерные для примера RTOS (VxWorks®) и включить параметры, требуемые целевым RTOS.
Реализация авторского блока является усовершенствованной темой, требуя знакомства с форматом S-функции Simulink® MEX и API, и с Компилятором выходного языка (TLC). Эти темы затронуты в следующих документах:
Темы Simulink, Что такое S-функция? (Simulink), S-функции Использования в Моделях (Simulink), Как работа S-функций (Simulink) и S-функции Реализации (Simulink) описывает S-функции MEX и API S-функции в целом.
S-функции Встраивания (Simulink Coder), Встройте S-функции MEX C (Simulink Coder), и S-функции и Генерация кода (Simulink Coder) описывают, как создать реализацию блока 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.
res
является значением параметров Timer resolution (seconds).
Следующая выборка кода показывает вызов 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, не принимайте, что сигналы порта являются инвариантными. Для получения дополнительной информации видят Встроенные Инвариантные Сигналы (Simulink Coder). Если блок не является инвариантным, генератор кода производит код только в инициализировать функции точки входа. Если блок является инвариантным, генератор кода не производит код для блока.
В этом разделе рассматриваются каждую функцию 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 и индекс вызова, возвращает запись блока для нисходящего блока подсистемы вызова функции. |
| Обеспечивает доступ к счетчику времени восходящей асинхронной задачи. |
| Обеспечивает доступ к высокому слову счетчика времени восходящей асинхронной задачи. |
| Определяет, нужна ли асинхронная задача в счетчике и управляет его собственным таймером. |
| Если блок вызова требует асинхронного счетчика, возвращает |
| Возвращает код, который устанавливает счетчики |
| Генерирует код, чтобы установить значение деления асинхронного счетчика блока. |
| Генерирует код, чтобы установить значение деления высокого слова асинхронного счетчика блока |