Открыть сервис

NVIC

NVIC (Nested Vectored Interrupt Controller) — это встроенный модуль управления прерываниями, реализованный в микроконтроллерах на базе ядер ARM Cortex-M (M0, M3, M4, M7 и более поздних). Он обеспечивает приоритетную обработку аппаратных и программных прерываний с поддержкой вложенности, векторизации и маскирования, что является ключевым элементом архитектуры реального времени в системах на кристалле (SoC).

Архитектура и принцип работы

NVIC является частью блока System Control Block (SCB) в ядрах Cortex-M. Его основная функция — приём сигналов от периферийных устройств (таймеров, портов ввода-вывода, коммуникационных интерфейсов) и внешних источников, определение их приоритетов, и передача процессору адреса соответствующей функции-обработчика (вектора прерывания). В отличие от традиционных контроллеров прерываний (например, PIC в x86 или старых ARM7), NVIC не требует опроса внешних регистров для определения источника — он автоматически загружает адрес из таблицы векторов, расположенной в начале адресного пространства памяти.

Векторизация и таблица векторов

Каждое прерывание имеет фиксированный номер (IRQn), который соответствует индексу в таблице векторов. Таблица содержит адреса обработчиков для всех исключений и прерываний. При возникновении прерывания NVIC извлекает адрес из таблицы по номеру IRQn и передаёт управление процессору. Это обеспечивает минимальную задержку входа в обработчик (латентность), которая для Cortex-M3/M4 составляет 12 тактов при отсутствии вложенности.

Вложенность и приоритеты

NVIC поддерживает до 256 уровней приоритета (в зависимости от реализации — 8, 16, 32, 64 или 256). Приоритеты задаются программно через регистры NVIC_IPR (Interrupt Priority Registers). Если во время выполнения обработчика с низким приоритетом поступает сигнал с более высоким приоритетом, NVIC приостанавливает текущий обработчик и запускает более приоритетный. После завершения высокоприоритетного обработчика выполнение низкоприоритетного возобновляется. Это называется вложенностью прерываний.

Маскирование и глобальное отключение

Прерывания можно временно запретить глобально с помощью инструкции CPSID I (или __disable_irq() в C) или разрешить через CPSIE I. Кроме того, NVIC позволяет индивидуально маскировать каждое прерывание через регистр NVIC_ICER (Interrupt Clear-Enable Register). Для систем реального времени критически важно минимизировать время отключения прерываний, чтобы не пропустить события.

Классификация прерываний в NVIC

Прерывания в архитектуре Cortex-M делятся на два основных типа:

  • Системные исключения — внутренние события ядра (сброс, неисправимая ошибка, сбой шины, прерывание по системному таймеру SysTick, программное прерывание PendSV, вызов супервизора SVC). Они имеют фиксированные номера от -15 до -1 (в таблице векторов).
  • Внешние прерываниясигналы от периферийных модулей и внешних выводов. Нумеруются от 0 до 239 (в зависимости от числа поддерживаемых линий в конкретном микроконтроллере). Каждое внешнее прерывание может быть настроено на фронт, спад или уровень сигнала.

Регистры управления

NVIC управляется через набор регистров, отображаемых в адресное пространство памяти (Memory-Mapped I/O). Основные из них:

  • NVIC_ISER (Interrupt Set-Enable Register) — разрешает прерывание.
  • NVIC_ICER (Interrupt Clear-Enable Register) — запрещает прерывание.
  • NVIC_ISPR (Interrupt Set-Pending Register) — устанавливает флаг ожидания (программный вызов прерывания).
  • NVIC_ICPR (Interrupt Clear-Pending Register) — сбрасывает флаг ожидания.
  • NVIC_IABR (Interrupt Active Bit Register) — показывает, какое прерывание выполняется в данный момент.
  • NVIC_IPR (Interrupt Priority Register) — задаёт приоритет для каждого прерывания (4 бита на прерывание, но число используемых бит зависит от реализации).

Особенности реализации в разных ядрах

  • Cortex-M0/M0+ — поддерживают только 32 внешних прерывания и 4 уровня приоритета (2 бита). Векторизация упрощена, нет поддержки вложенности в полном объёме (приоритеты фиксированы).
  • Cortex-M3/M4 — до 240 внешних прерываний, до 256 уровней приоритета (8 бит), полная вложенность, поддержка Tail-Chaining (сокращение задержки между последовательными прерываниями) и Late-Arrival (обработка прерывания, пришедшего во время входа в другое).
  • Cortex-M7 — аналогичен M4, но с дополнительными возможностями для кэш-памяти и FPU.

Применение

NVIC является стандартным компонентом подавляющего большинства современных микроконтроллеров на базе ARM Cortex-M, используемых в:

  • Промышленной автоматикеПЛК, датчики, приводы.
  • Потребительской электронике — пульты, игрушки, бытовая техника.
  • Автомобильной электронике — блоки управления двигателем, ABS, подушки безопасности.
  • Медицинских устройствах — портативные мониторы, инсулиновые помпы.
  • Интернете вещей (IoT) — датчики, умные розетки, носимые устройства.

Преимущества и недостатки

Преимущества:

  • Минимальная и детерминированная задержка обработки прерываний (12–15 тактов).
  • Аппаратная поддержка вложенности без программного сохранения контекста.
  • Гибкая настройка приоритетов и маскирования.
  • Встроенная поддержка в компиляторах (CMSIS — Cortex Microcontroller Software Interface Standard).

Недостатки:

  • Фиксированное число линий прерываний (ограничено ядром).
  • Зависимость от производителя микроконтроллера в части распределения номеров IRQn.
  • Отсутствие поддержки внешних контроллеров прерываний (например, GIC в Cortex-A) — для сложных многоядерных систем NVIC не подходит.

Программирование NVIC

В среде разработки на языке C для ARM Cortex-M работа с NVIC обычно осуществляется через CMSIS-функции:

``c NVIC_EnableIRQ(IRQn); // Разрешить прерывание NVIC_DisableIRQ(IRQn); // Запретить прерывание NVIC_SetPriority(IRQn, prio); // Установить приоритет NVIC_GetPendingIRQ(IRQn); // Проверить ожидание NVIC_SetPendingIRQ(IRQn); // Программно вызвать прерывание ``

Для обработки прерывания необходимо определить функцию с именем, соответствующим имени в таблице векторов (например, USART1_IRQHandler). В современных средах (Keil, IAR, GCC) имена обработчиков задаются в startup-файле.

Сравнение с альтернативами

  • PIC (Programmable Interrupt Controller) — используется в архитектуре x86, требует внешнего чипа (например, 8259A), имеет меньше уровней приоритета и не поддерживает вложенность аппаратно.
  • GIC (Generic Interrupt Controller) — применяется в ядрах ARM Cortex-A (для Linux/Android), поддерживает многоядерность, но имеет большую латентность и сложность.
  • PLIC (Platform-Level Interrupt Controller) — в архитектуре RISC-V, децентрализован, требует программного опроса.

NVIC остаётся де-факто стандартом для однопроцессорных систем реального времени на ARM Cortex-M благодаря простоте, эффективности и широкой поддержке.

Интересные факты

  • NVIC впервые появился в ядре ARM Cortex-M3 (2004 год) и с тех пор практически не изменился в базовой функциональности.
  • В микроконтроллерах STM32 (на базе Cortex-M) NVIC интегрирован с вложенным контроллером прерываний (EXTI) для внешних выводов.
  • Программное прерывание PendSV используется в операционных системах реального времени (RTOS) для переключения контекста задач без блокировки других прерываний.

Источники

  • ARM Architecture Reference Manual ARMv7-M (ARM DDI 0403)
  • ARM Cortex-M3 Technical Reference Manual (ARM DDI 0337)
  • Joseph Yiu, «The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors», 3rd Edition
  • CMSIS-Core Documentation (ARM)
  • STMicroelectronics, «STM32F4xx Reference Manual» (RM0090)

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →