Сгенерируйте стандартные программы прерывания обслуживания

Чтобы сгенерировать стандартную программу обработки прерывания (ISR), связанную с определенным уровнем прерывания VME для примера RTOS (VxWorks®), используйте блок Async Interrupt. Блок Async Interrupt включает заданный уровень прерывания и устанавливает ISR, который вызывает подсистему вызова подключенной функции.

Можно также использовать блок Async Interrupt в симуляции. Он предоставляет порт входа, который может быть включен и подключен к моделируемому источнику прерывания.

Примечание

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

Подключение блока асинхронного прерывания

Чтобы сгенерировать ISR, соедините выход блока Async Interrupt с управляющим входом

  • Подсистема вызова функции

  • Вход блока Task Sync

  • Вход в Stateflow® график, сконфигурированный для входного события вызова функции

Следующий рисунок показывает блок Async Interrupt, сконфигурированный для обслуживания двух источников прерывания. Выходы (ширина сигнала 2) соединяются с двумя подсистемами вызова функции.

Требования и ограничения

Обратите внимание на следующие требования и ограничения:

  • Блок Async Interrupt поддерживает прерывания VME с 1 по 7.

  • Блок Async Interrupt использует следующие системные вызовы к примеру RTOS (VxWorks):

    • sysIntEnable

    • sysIntDisable

    • intConnect

    • intLock

    • intUnlock

    • tickGet

Факторы о эффективности

Выполнение больших подсистем на уровне прерывания может оказать значительное влияние на время отклика прерывания для прерываний равного и низкого приоритета в системе. Как правило, лучше всего держать ISR как можно короче. Соедините только подсистемы вызова функции, которые содержат небольшое количество блоков, с блоком Async Interrupt.

Лучшим решением для больших подсистем является использование блока Task Sync для синхронизации выполнения подсистемы вызова функции с задачей RTOS. Блок Task Sync помещается между блоком Async Interrupt и подсистемой вызова функции. Блок Async Interrupt затем устанавливает блок Task Sync как ISR. ISR освобождает семафор синхронизации (выполняет semGive) к задаче, и возвращается сразу с уровня прерывания. Затем задание планируется и запускается примером RTOS (VxWorks). Для получения дополнительной информации см. раздел «Распространение и синхронизация выполнения задачи RTOS».

Использование блока асинхронного прерывания в симуляции и генерации кода

В этом разделе описывается подход с двумя моделями к разработке и реализации систем в реальном времени, которые включают ISR. В этом подходе вы разрабатываете одну модель, которая включает в себя объект и контроллер для симуляции, и другую модель, которая включает в себя только контроллер для генерации кода. Использование Simulink® библиотека, можно реализовать изменения в обеих моделях одновременно. Следующий рисунок показывает, как изменения, внесенные в объект или контроллер, оба из которых находятся в библиотеке, распространяются на модели.

Двухмодельное использование блока асинхронного прерывания для симуляции и генерации кода

Также возможен подход с одной моделью. В этом подходе компонент Plant модели активен только в симуляции. Во время генерации кода компоненты Plant эффективно выключаются из системы, и код генерируется только для блоков прерывания и частей контроллера модели. Пример этого подхода см. в rtwdemo_async модель.

Подход с двумя моделями: симуляция

Следующий блок показывает простую модель, которая иллюстрирует подход к моделированию с двумя моделями. Во время симуляции блоки Импульсного Генератора обеспечивают имитированные сигналы прерывания.

Имитированные сигналы прерывания маршрутизируются через входной порт Async Interrupt блока. При получении моделируемого прерывания блок вызывает подключенную подсистему.

Во время симуляции подсистемы, соединенные с выходами Async Interrupt блоков, выполняются в порядке их приоритета в примере RTOS (VxWorks). В случае одновременного возникновения двух или более сигналов прерывания, блок Async Interrupt выполняет системы нижнего потока в порядке, заданном их уровнями прерывания (уровень 7 получает наивысший приоритет). Первый входной элемент преобразуется в первый выходной элемент.

Можно также использовать блок Async Interrupt в симуляции, не включая вход симуляции. В таком случае Async Interrupt блок наследует базовую скорость модели и вызывает подключенные подсистемы в порядке их приоритетов в RTOS. (В этом случае блок Async Interrupt ведет себя как если бы все входы получили 1 одновременно.)

Подход с двумя моделями: генерация кода

В сгенерированном коде для выборки,

  • Ground блоки обеспечивают входные сигналы блоку Окружения Контроллера

  • Блок Async Interrupt не использует свой вход симуляции

Блоки Ground управляют входом блока Контроллер, поэтому код не генерируется для этого пути сигнала. Генератор кода не производит код для блоков, которые управляют входом управления симуляцией в блок Контроллер, потому что этот путь не выбран во время генерации кода. Однако шаги расчета управляющих блоков для входов симуляции в блоке Контроллер способствуют шагам расчета, поддерживаемым в сгенерированном коде. Чтобы избежать включения ненужных шагов расчета в сгенерированный код, используйте шаги расчета блоков, управляющих входом симуляции в модели, где сгенерированный код предназначен.

Автономные функции устанавливаются как ISR, и таблица векторов прерывания выглядит следующим образом:

Смещение 
192&isr_num1_vec192()
193&isr_num2_vec193()

Рассмотрим код, сгенерированный из этой модели, принимая, что Async Interrupt параметров блоков сконфигурированы, как показано на следующем рисунке.

Код инициализации

В сгенерированном коде Async Interrupt блок устанавливает код в блоки Subsystem как стандартные программы обслуживания прерывания. Векторы прерывания для IRQ1 и IRQ2 хранятся в местоположениях 192 и 193 относительно основы таблицы векторов прерывания, заданной параметром VME interrupt vector offset(s).

Для установки ISR требуется два вызова RTOS (VxWorks). int_connect и sysInt_Enable. Блок Async Interrupt вставляет эти вызовы в model_initialize функция, как показано на следующем фрагменте кода.

/* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
    /* Connect and enable ISR function: isr_num1_vec192 */
    if( intConnect(INUM_TO_IVEC(192), isr_num1_vec192, 0) != OK) {
      printf("intConnect failed for ISR 1.\n");
    }
    sysIntEnable(1);

    /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
    /* Connect and enable ISR function: isr_num2_vec193 */
    if( intConnect(INUM_TO_IVEC(193), isr_num2_vec193, 0) != OK)
    {
      printf("intConnect failed for ISR 2.\n");
    }
    sysIntEnable(2);

Оборудование, которое генерирует прерывание, не сконфигурировано блоком Async Interrupt. Как правило, источником прерывания является плата ввода-вывода VME, которая генерирует прерывания для определенных событий (для примера, конца A/D преобразования). Уровень прерывания VME и вектор настраиваются в регистрах или с помощью перемычек на плате. Вы можете использовать mdlStart Стандартная программа записанного пользователем драйвера устройства (S-функция) для настройки регистров и включения генерации прерываний на плате. Вы должны соответствовать уровню прерывания и вектору, указанному в диалоговом окне Async Interrupt блока, уровню и вектору, установленным на плате ввода-вывода.

Сгенерированный код ISR

Фактический ISR, сгенерированный для IRQ1 в RTOS (VxWorks) приведен ниже.

/* VxWorks Interrupt Block: '<Root>/Async Interrupt' */

void isr_num1_vec192(void)
{
  int_T lock;
  FP_CONTEXT context;

   /* Use tickGet() as a portable tick counter example. 
      A much higher resolution can be achieved with a 
      hardware counter */
   Async_Code_M->Timing.clockTick2 = tickGet();

   /* disable interrupts (system is configured as non-ive) */
   lock = intLock();

   /* save floating point context */
   fppSave(&context);
 
   /* Call the system: <Root>/Subsystem A */
   Count(0, 0);

   /* restore floating point context */
   fppRestore(&context);

   /* re-enable interrupts */
   intUnlock(lock);
}

Существует несколько функций ISR, которые следует отметить:

  • Из-за установки параметра Preemption Flag(s) этот ISR заблокирован; то есть он не может быть упрежден прерыванием с более высоким приоритетом. ISR блокируется и разблокируется в примере RTOS (VxWorks) int_lock и int_unlock функций.

  • Подключенная подсистема, Count, вызывается из ISR.

  • Count функция выполняет алгоритмический (модельный) код. Поэтому контекст с плавающей точкой сохраняется и восстанавливается через вызов в Count.

  • ISR поддерживает свой собственный абсолютный счетчик времени, который отличается от других периодических счетчиков базовой скорости или субрейта в системе. Данные синхронизации поддерживаются для использования любых блоков, выполненных в ISR, которые требуют абсолютного или истекшего времени.

    Для получения дополнительной информации см. раздел Таймеры в асинхронных задачах.

Моделируйте код окончания

Функция завершения модели отключает прерывания в RTOS (VxWorks):

/* Model terminate function */
void Async_Code_terminate(void)
{
   /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
   /* Disable interrupt for ISR system: isr_num1_vec192 */
   sysIntDisable(1);

   /* VxWorks Interrupt Block: '<Root>/Async Interrupt' */
   /* Disable interrupt for ISR system: isr_num2_vec193 */
   sysIntDisable(2);
}

Похожие темы