В этом разделе описывается, как реализовать асинхронные блоки для использования с целевой RTOS, используя блоки Async Interrupt и Task Sync в качестве начальной точки. Rate Transition блоки не зависят от цели, поэтому вам не нужно разрабатывать настраиваемые переходные блоки скорости.
Примечание
Методы интегрирования операционных систем, которые показаны в этом разделе, используют один или несколько блоков в vxlib1
библиотека. Эти блоки предоставляют примеры начальной точки, которые помогают вам разрабатывать пользовательские блоки для вашего целевого окружения.
Вы можете настроить асинхронные библиотечные блоки, изменив реализацию блока. Эти файлы являются
Базовая S-функция блока Файла MEX
Файлы TLC, которые код системы управления генерацию блока
В сложение необходимо изменить маски блоков, чтобы удалить ссылки, характерные для примера RTOS (VxWorks®) и включать параметры, требуемые вашей целевой RTOS.
Реализация пользовательских блоков является расширенной темой, требующей ознакомления с Simulink® Формат MEX S-функции и API, а также с Target Language Compiler (TLC). Эти темы рассматриваются в следующих документах:
Темы Simulink Что такое S-функция?, Использование S-функций в моделях, Как работают S-функции и реализация S-функций описывают S-функции MEX и API S-функции в целом.
Inlining S-Functions, Inline C MEX S-Functions и S-Functions and Code Generation описывают, как создать реализацию блока TLC для использования в генерации кода.
В следующих разделах рассматриваются реализации C/C + + и TLC блоков асинхронной библиотеки, включая необходимые SimStruct
макросы и функции в библиотеке асинхронной поддержки TLC (asynclib.tlc
).
Исходные файлы для блока Async Interrupt расположены в
(открыто):matlabroot
/ rtw/c/tornado/устройства
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 шаг расчета блока, не принимайте, что сигналы порта инвариантны. Для получения дополнительной информации см. «Входные инвариантные сигналы». Если блок не инвариантен, генератор кода производит код только в функции initialize entry-point. Если блок инвариантен, генератор кода не производит код для блока.
В этом разделе рассматриваются каждая функция 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/устройства
vxtask1.cpp
: Исходный код файла MEX, для использования в строении и симуляции.
vxtask1.tlc
: Реализация TLC для использования в генерации кода.
asynclib.tlc
: библиотека функций поддержки TLC, вызываемая реализацией TLC блока. Вызовы библиотеки суммируются в библиотеке поддержки asynclib.tlc.
Как и блок Async Interrupt, блок Task Sync настраивает таймер, в этом случае с фиксированным разрешением. Приоритет задачи, связанной с блоком, получен из параметров блоков Simulink task priority. The 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), которая ожидает семафор. Когда он получает семафор, он обновляет таймер такта блока и вызывает дочерний подсистемный код, как описано в Spawn и Synchronize Execution of RTOS Task. Outputs
также генерирует код (вызываемый с уровня прерывания), который предоставляет семафор.
Оконечная функция. Terminate
функция генерирует вызов RTOS (VxWorks) в качестве примера taskDelete
завершить выполнение задачи, порождаемой блоком. Необходимо заменить это вызовами целевой RTOS.
Обратите внимание также, что, если целевой RTOS динамически выделил память, связанную с задачей, Terminate
функция должна отменить выделение памяти.
asynclib.tlc
- библиотека функций TLC, поддерживающих реализацию асинхронных блоков. Некоторые функции специально разработаны для использования в асинхронных блоках. Для примера, LibSetAsyncCounter
генерирует вызов для обновления таймера для асинхронного блока. Другими функциями являются утилиты, которые возвращают информацию, требуемую асинхронными блоками (для примера, информацию о связанных подсистемах вызова функции).
В следующей таблице приведены общие вызовы в библиотеке. Для получения дополнительной информации смотрите исходный код библиотеки и vxinterrupt1.tlc
и vxtask1.tlc
файлы, которые вызывают функции библиотеки.
Сводные данные функций библиотеки asynclib.tlc
Функция | Описание |
---|---|
| Для использования встроенными S-функциями с выходами вызова функции. Генерирует код для выполнения подсистемы вызова функции. |
| Возвращает значение поля из блочной записи. |
| Учитывая блок S-Function и индекс вызова, возвращает запись блока для подсистемы вызова нисходящей функции. |
| Предоставляет доступ к счетчику времени для асинхронной задачи в восходящем направлении. |
| Предоставляет доступ к высокому слову счетчика времени восходящей асинхронной задачи. |
| Определяет, нужен ли асинхронной задаче счетчик, и управляет собственным таймером. |
| Если вызывающий блок требует асинхронного счетчика, возвращается |
| Возвращает код, который устанавливает |
| Генерирует код, чтобы задать значение деления для асинхронного счетчика блока. |
| Генерирует код, чтобы задать значение деления высокого слова асинхронного счетчика блока |