exponenta event banner

Создание настраиваемой асинхронной библиотеки

В этом разделе описывается, как реализовать асинхронные блоки для использования с целевой RTOS, используя блоки асинхронного прерывания и синхронизации задач в качестве начальной точки. Блоки Rate Transition не зависят от цели, поэтому не требуется разрабатывать настраиваемые блоки Rate Transition.

Примечание

Методы интеграции операционной системы, показанные в этом разделе, используют один или несколько блоков в vxlib1 библиотека. Эти блоки содержат начальные примеры, помогающие разрабатывать пользовательские блоки для целевой среды.

Сведения о внедрении асинхронных блоков

Можно настроить асинхронные блоки библиотеки, изменив реализацию блоков. Эти файлы

  • Основной файл MEX S-функции блока

  • Файлы TLC, управляющие формированием кода блока

Кроме того, необходимо изменить маски блоков, чтобы удалить ссылки, относящиеся к примеру RTOS (VxWorks ®), и включить параметры, требуемые целевой RTOS.

Реализация пользовательского блока - это усовершенствованная тема, требующая ознакомления с форматом и API функции Simulink ® MEX S, а также с компилятором целевого языка (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.

Реализация блока C MEX

Большая часть кода в 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, не предполагайте, что сигналы порта являются инвариантными. Дополнительные сведения см. в разделе Инлайн инвариантные сигналы. Если блок не инвариантен, генератор кода производит код только в функции инициализации точки входа. Если блок инвариантен, генератор кода не производит код для блока.

Внедрение TLC

В этом разделе рассматривается каждая функция vxinterrupt1.tlcс акцентом на специфичные для цели функции, которые необходимо изменить для создания кода для целевой RTOS.

Создать директивы # include  .vxinterrupt1.tlc начинается с оператора

%include "vxlib.tlc"

vxlib.tlc является целевым файлом, который генерирует директивы для включения файлов заголовков для примера RTOS (VxWorks). Необходимо заменить его файлом, который создает include для целевой RTOS.

Функция установки BlockInstureSetup.  Для каждого подключенного выхода блока асинхронного прерывания, BlockInstanceSetup определяет имя функции для соответствующего ISR в сгенерированном коде. Имена функций имеют вид

isr_num_vec_offset

где num - номер ISR, определенный для номера (ов) прерывания (ов) параметра блока VME, иoffset - смещение таблицы прерываний, определяемое параметром блока VME смещение вектора прерываний.

В пользовательской реализации это соглашение об именовании является необязательным.

Имена функций кэшируются для использования 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.

Реализация блока C MEX

Как и блок асинхронного прерывания, блок синхронизации задач устанавливает таймер, в данном случае с фиксированным разрешением. Приоритет задачи, связанной с блоком, получают из параметра блока Приоритет задачи 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 |
}

Внедрение TLC

Создать директивы # 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

asynclib.tlc - библиотека функций TLC, поддерживающих реализацию асинхронных блоков. Некоторые функции специально разработаны для использования в асинхронных блоках. Например, LibSetAsyncCounter генерирует вызов для обновления таймера для асинхронного блока. Другими функциями являются утилиты, возвращающие информацию, требуемую асинхронными блоками (например, информацию о подключенных подсистемах вызова функций).

В следующей таблице представлены общие вызовы в библиотеке. Дополнительные сведения см. в исходном коде библиотеки и vxinterrupt1.tlc и vxtask1.tlc файлы, которые вызывают функции библиотеки.

Сводка функций библиотеки asynclib.tlc

Функция

Описание

LibBlockExecuteFcnCall

Для использования встроенными S-функциями с выходами вызова функции. Генерирует код для выполнения подсистемы вызова функции.

LibGetBlockAttribute

Возвращает значение поля из записи блока.

LibGetFcnCallBlock

При наличии S-функционального блока и индекса вызова возвращается запись блока для блока подсистемы вызова функции в нисходящем направлении.

LibGetCallerClockTickCounter

Обеспечивает доступ к счетчику времени асинхронной задачи в восходящем направлении.

LibGetCallerClockTickCounterHighWord

Обеспечивает доступ к старшему слову счетчика времени асинхронной задачи в восходящем направлении.

LibManageAsyncCounter

Определяет необходимость счетчика для асинхронной задачи и управляет собственным таймером.

LibNeedAsyncCounter

Если вызывающий блок требует асинхронного счетчика, возвращает TLC_TRUE, в противном случае возвращается TLC_FALSE.

LibSetAsyncClockTicks

Возвращает код, который задает clockTick счетчики, которые должны поддерживаться асинхронной задачей.

LibSetAsyncCounter

Создает код для установки значения засечки асинхронного счетчика блока.

LibSetAsyncCounterHighWord

Создает код для установки значения засечки верхнего слова асинхронного счетчика блока

Связанные темы