В этом разделе описывается, как реализовать асинхронные блоки для использования с целевой RTOS, используя блоки асинхронного прерывания и синхронизации задач в качестве начальной точки. Блоки Rate Transition не зависят от цели, поэтому не требуется разрабатывать настраиваемые блоки Rate Transition.
Примечание
Методы интеграции операционной системы, показанные в этом разделе, используют один или несколько блоков в vxlib1 библиотека. Эти блоки содержат начальные примеры, помогающие разрабатывать пользовательские блоки для целевой среды.
Можно настроить асинхронные блоки библиотеки, изменив реализацию блоков. Эти файлы
Основной файл MEX S-функции блока
Файлы TLC, управляющие формированием кода блока
Кроме того, необходимо изменить маски блоков, чтобы удалить ссылки, относящиеся к примеру RTOS (VxWorks ®), и включить параметры, требуемые целевой RTOS.
Реализация пользовательского блока - это усовершенствованная тема, требующая ознакомления с форматом и API функции Simulink ® MEX S, а также с компилятором целевого языка (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).
Исходные файлы для блока асинхронного прерывания находятся в (открыто):matlabroot/rtw/c/tornado/devices
vxinterrupt1.cИсходный код C MEX-файла для использования в конфигурации и моделировании
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 объявляет, что блок требует таймера, и устанавливает разрешение таймера, указанное для параметра блока Разрешение таймера (секунды).
Прототипом функции является
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.
Прототипом функции является
ssSetAsyncTaskPriorities(SimStruct *S, int numISRs,
int *priorityArray)где
S является SimStruct указатель.
numISRs - количество прерываний, указанное для номера (ов) прерываний VME параметра блока.
priorityarray - это целочисленный массив, содержащий номера прерываний, указанные для номера прерываний параметра блока VME.
Следующий фрагмент кода показывает вызов 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). Необходимо заменить его файлом, который создает include для целевой RTOS.
Функция установки BlockInstureSetup. Для каждого подключенного выхода блока асинхронного прерывания, BlockInstanceSetup определяет имя функции для соответствующего ISR в сгенерированном коде. Имена функций имеют вид
isr_num_vec_offset
где - номер ISR, определенный для номера (ов) прерывания (ов) параметра блока VME, иnum - смещение таблицы прерываний, определяемое параметром блока VME смещение вектора прерываний.offset
В пользовательской реализации это соглашение об именовании является необязательным.
Имена функций кэшируются для использования Outputs , которая генерирует фактический код ISR.
Функция вывода. Outputs выполняет итерации по подключенным выходам блока асинхронного прерывания. Для каждого такого выхода генерируется ISR.
Код ISR кэшируется в "Functions" раздел сформированного кода. Перед созданием ISR, Outputs выполняет следующее:
Генерирует вызов дочернего блока (кэшируется во временном буфере).
Определяет, должен ли ISR быть заблокирован (как указано параметром блока Preemption Flag (s)).
Определяет, является ли блок, подключенный к блоку асинхронного прерывания, блоком синхронизации задач. (Эта информация получена с помощью 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.
Исходные файлы для блока синхронизации задач находятся в (открыто). Они являютсяmatlabroot/rtw/c/tornado/devices
vxtask1.cpp: Исходный код MEX-файла, для использования в конфигурации и моделировании.
vxtask1.tlcРеализация TLC для использования при создании кода.
asynclib.tlc: библиотека функций поддержки TLC, вызываемая реализацией TLC блока. Вызовы библиотеки обобщаются в библиотеке поддержки asynclib.tlc.
Как и блок асинхронного прерывания, блок синхронизации задач устанавливает таймер, в данном случае с фиксированным разрешением. Приоритет задачи, связанной с блоком, получают из параметра блока Приоритет задачи Simulink. SS_OPTION те же параметры, что и для блока асинхронного прерывания.
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). Необходимо заменить его файлом, который создает include для целевой RTOS.
Функция установки BlockInstureSetup. BlockInstanceSetup функция выводит имя задачи, имя блока и другие идентификаторы, используемые в дальнейшем при создании кода. Он также проверяет и предупреждает о несвязанных условиях блоков и генерирует объявление хранилища для семафора (stopSem), которая используется в случае переполнения прерываний.
Запустить функцию. Start функция генерирует требуемые вызовы RTOS (VxWorks) для определения хранилища для семафора, используемого при управлении задачей, порожденной блоком синхронизации задач. В зависимости от значения 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-функционального блока и индекса вызова возвращается запись блока для блока подсистемы вызова функции в нисходящем направлении. |
| Обеспечивает доступ к счетчику времени асинхронной задачи в восходящем направлении. |
| Обеспечивает доступ к старшему слову счетчика времени асинхронной задачи в восходящем направлении. |
| Определяет необходимость счетчика для асинхронной задачи и управляет собственным таймером. |
| Если вызывающий блок требует асинхронного счетчика, возвращает |
| Возвращает код, который задает |
| Генерирует код для установки значения засечки асинхронного счетчика блока. |
| Создает код для установки значения засечки верхнего слова асинхронного счетчика блока |