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 →


