Прерывания в embedded-системах воспринимаются как благо: быстрый отклик, экономия ресурсов, «реакция по событию».
Но на практике именно прерывания часто становятся причиной плавающих багов, редких зависаний и поведения «раз в неделю, но навсегда».
Разберёмся, почему так происходит.
Иллюзия «быстрого и безопасного» кода
Основная ошибка — воспринимать обработчик прерывания как «обычную функцию, только быстрее».
На самом деле ISR — это код, который:
-
выполняется вне нормального потока программы
-
может прервать выполнение в любой момент
-
работает с ограниченным стеком
-
влияет на тайминги всей системы
Чем больше логики внутри ISR — тем выше риск нестабильности.
Накопление прерываний и скрытая перегрузка
Если источник прерывания срабатывает быстрее, чем ISR успевает отработать:
-
флаги начинают накапливаться
-
растёт латентность других прерываний
-
появляются пропуски событий
Система может не падать, но:
-
тайминги «плывут»
-
протоколы начинают давать ошибки
-
watchdog срабатывает без видимой причины
Особенно часто это встречается при:
-
работе с UART на высоких скоростях
-
таймерах с коротким периодом
-
АЦП с частыми выборками
Приоритеты: источник хаоса №1
Неправильно расставленные приоритеты прерываний приводят к:
-
взаимным блокировкам
-
голоданию низкоприоритетных задач
-
непредсказуемым задержкам
Типичная ошибка — давать «высокий приоритет всему важному».
В итоге важным оказывается слишком много.
Общие данные и гонки

ISR и основной код почти всегда работают с общими ресурсами:
-
буферы
-
флаги состояния
-
счётчики
Без строгой синхронизации это приводит к:
-
повреждению данных
-
частичным записям
-
багам, которые невозможно воспроизвести отладчиком
Особенно опасны:
-
много байтовые структуры
-
16/32-битные переменные на 8-битных МК
-
операции чтение-модификация-запись
Вложенные прерывания и стек
Вложенные прерывания выглядят удобно, но:
-
быстро увеличивают использование стека
-
усложняют анализ таймингов
-
делают сбои «неуловимыми»
Переполнение стека в ISR — одна из самых неприятных причин нестабильности: устройство может работать дни, прежде чем сломаться.
Что делать, чтобы прерывания не ломали систему
Практика, которая реально работает:
-
ISR делает минимум: установить флаг, сохранить байт, выйти
-
вся логика — в основном цикле или RTOS-задаче
-
чёткая схема приоритетов (не «на глаз»)
-
контроль времени выполнения ISR
-
защита общих данных (atomic, critical sections)
-
мониторинг стека и нагрузки
Прерывания должны быть механизмом доставки событий, а не местом для логики.
Прерывания — мощный инструмент, но: чем больше «ума» в ISR, тем менее предсказуема система.
Стабильные embedded-проекты строятся не на количестве прерываний, а на архитектуре работы с ними.
Именно на этом уровне — архитектуры, таймингов и реальных условий эксплуатации — чаще всего и требуется инженерный разбор, а не просто выбор микроконтроллера или платы.
