Bare metal, FreeRTOS или Zephyr: как выбрать архитектуру
Архитектуру прошивки стоит выбирать до того, как драйверы, протоколы и бизнес-логика переплетутся в одном главном цикле. Bare metal даёт минимальный накладной расход и полный контроль. FreeRTOS добавляет компактное ядро задач, очередей и синхронизации. Zephyr предлагает не только ядро, но и унифицированные драйверы, device tree, сетевые стеки, подсистемы обновления, безопасности и сборки. Ни один вариант не является автоматически «профессиональнее». Небольшой датчик с одним интерфейсом может надёжнее работать без RTOS. Сложное сетевое устройство трудно поддерживать в самодельном scheduler. Правильный выбор определяется числом конкурентных функций, временными требованиями, командой, жизненным циклом и объёмом стороннего кода.
Опишите события и сроки реакции
Составьте таблицу всех событий: периодический опрос, вход прерывания, пакет связи, запись Flash, обновление дисплея, управление приводом, watchdog. Для каждого укажите период, дедлайн, максимальное время обработки и допустимость задержки. Различайте hard real-time, где пропуск срока опасен, и soft real-time, где он лишь ухудшает качество.
Если существует один короткий цикл с понятной последовательностью, bare metal остаётся прозрачным. Когда операции блокируются, имеют разные приоритеты и обмениваются данными, RTOS позволяет явно выразить конкурентность. Но RTOS не исправляет плохо рассчитанное время выполнения: задача высокого приоритета может занять процессор и сорвать все остальные дедлайны.
Когда достаточен bare metal
Типовая архитектура состоит из прерываний, конечных автоматов и неблокирующего главного цикла. Она подходит для небольшого MCU, минимального энергопотребления, строгого контроля памяти и простой сертифицируемой функции. Код легко проследить, если каждое действие короткое, а состояние описано явно.
Главная опасность — постепенное появление скрытых блокировок. delay(), ожидание UART, стирание Flash или долгая обработка пакета задерживают остальные функции. Поэтому bare metal требует дисциплины: драйверы должны быть асинхронными, тяжёлая работа — дробиться на шаги, а все временные бюджеты — измеряться.
Что добавляет FreeRTOS
FreeRTOS предоставляет scheduler, задачи, очереди, semaphore, mutex, event groups, software timers и уведомления задач. Он удобен, когда несколько относительно независимых функций должны ждать события без ручного конечного автомата. Переносимость ядра и широкий набор портов упрощают миграцию между MCU.
FreeRTOS не диктует полную платформу. HAL, сетевой стек, файловая система, обновление и криптография выбираются отдельно. Это даёт гибкость, но увеличивает ответственность команды за совместимые версии и интеграцию. Архитектура проекта должна определить владельца каждого периферийного блока и правила передачи данных между задачами.
Что добавляет Zephyr
Zephyr объединяет ядро RTOS с моделью плат и SoC, Kconfig, device tree, драйверами, Bluetooth, networking, storage, logging, power management и инфраструктурой тестирования. Это полезно для продукта, где требуется несколько протоколов, переносимость между платами и upstream-поддержка компонентов.
Цена — более высокий порог входа и зависимость от структуры проекта. Ошибка в Kconfig или devicetree может выглядеть как проблема драйвера. Нужно закреплять версию Zephyr или использовать LTS, отслеживать security advisories и хранить собственные board definitions так, чтобы обновление не превращалось в ручное слияние десятков патчей.
Рассчитайте RAM и стек
В bare metal обычно один основной стек и статические буферы. В RTOS каждая задача получает собственный стек, и их суммы быстро становятся заметными. Для задачи оценивают максимальную глубину вызовов, локальные массивы, обработку исключений и библиотеки форматирования. Затем включают аппаратный MPU или canary, stack overflow hook и измерение high-water mark.
Не задавайте всем задачам «по 4 Кбайт с запасом» на MCU с 128 Кбайт RAM. Сначала создайте нагрузочный сценарий, измерьте пик и добавьте обоснованный резерв. Учтите heap RTOS, сетевые pbuf, очереди, DMA-буферы, TLS и двойной образ обновления.
Приоритеты и инверсия приоритетов
Высокий приоритет назначают по дедлайну, а не по важности функции для бизнеса. Логирование может быть важным, но не должно прерывать контур управления. Если низкоприоритетная задача удерживает mutex, нужный высокой задаче, возникает инверсия приоритетов; mutex с inheritance уменьшает риск, но не заменяет короткую критическую секцию.
ISR должна выполнить минимум: зафиксировать время, забрать данные, очистить флаг и разбудить задачу. Нельзя вызывать из прерывания обычную блокирующую функцию RTOS. Для каждого API проверяйте вариант FromISR и необходимость переключения контекста после выхода.
Избегайте общих изменяемых данных
Очередь или message buffer обычно безопаснее глобальной структуры с mutex. Передавайте владение буфером явно: producer выделяет/заполняет, consumer освобождает либо возвращает в pool. Это особенно важно для DMA, где кэш и периферия могут видеть данные в разное время.
Для настроек используйте версионированную структуру и атомарную запись. Не позволяйте нескольким задачам независимо писать один раздел Flash. Отдельный storage service упрощает сериализацию и восстановление после сбоя питания.
Реальное время проверяется измерением
Средняя загрузка CPU ничего не говорит о максимальной задержке. Добавьте GPIO-маркеры, cycle counter или trace-инструмент и измерьте: latency от IRQ до задачи, execution time, длительность отключения прерываний, максимальную очередь и время удержания mutex. Прогоните худшее сочетание — сеть, запись Flash, диагностика и максимальная частота входов одновременно.
Включите assertions, watchdog для независимых подсистем и статистику stack/heap. Watchdog должен обнаруживать зависшую функцию, а не просто сбрасываться таймерной ISR независимо от здоровья приложения.
Энергопотребление и tickless idle
RTOS может помогать энергосбережению, если scheduler знает ближайший таймаут и переводит MCU в sleep. Но частый системный tick, активные таймеры или бесполезный polling не дадут войти в глубокий режим. Проверьте, какие источники могут разбудить систему и сколько занимает восстановление clocks/peripherals.
В Zephyr и vendor SDK режимы питания связаны с драйверами и device constraints; в собственном bare-metal проекте всё контролирует команда. В обоих случаях нужен энергетический trace полного сценария, а не ток одного режима из datasheet.
Обновление и безопасность
Сетевое устройство требует инвентаризации компонентов, управления ключами, secure boot, подписанного обновления и реакции на уязвимости. Платформа с готовой подсистемой может ускорить реализацию, однако включённая галочка не доказывает защищённость. Проверяются trust anchor, anti-rollback, защита debug, recovery и процесс ротации ключей.
Для долгого жизненного цикла закрепите release, compiler и конфигурацию. Регулярно переносите критические исправления, но не обновляйте всё дерево зависимостей прямо перед серийным выпуском без regression-тестов.
Что зафиксировать в архитектурном документе
До активной разработки оформите одну схему контекстов исполнения: ISR, задачи, приоритеты, таймеры, DMA и callback сторонних библиотек. Для каждого общего ресурса укажите владельца, способ синхронизации и максимальное время блокировки. Рядом приведите таблицу memory budget с Flash, статической RAM, stack каждой задачи, heap, сетевыми и обновочными буферами. Такой документ должен обновляться из измерений сборки, а не оставаться предварительной оценкой.
Зафиксируйте правила ошибок: где допустим retry, какая задача перезапускается, когда требуется reset всей системы и какие данные сохраняются перед ним. Определите health indicators, которые действительно подтверждают прогресс каждой подсистемы. В acceptance criteria включите максимальную latency критичного события, нулевое число переполнений очереди и stack margin при worst-case сценарии. Тогда спор bare metal/RTOS решается наблюдаемыми свойствами, а не предпочтением команды.
Практический пример выбора
Контроллер собирает четыре аналоговых канала каждые 100 мкс, управляет реле, ведёт Modbus, хранит журнал и обновляется по сети. Контур сбора должен иметь малый джиттер; сеть и Flash иногда блокируются. Bare metal возможен, но потребует нескольких сложных state machines. FreeRTOS позволяет выделить высокоприоритетную acquisition task, communication task и низкоприоритетный storage service.
Если позже добавятся BLE, IPv6, secure update и несколько плат, Zephyr может снизить интеграционную работу. Решение принимают через spike: на реальной плате измеряют ISR latency, RAM, время старта и готовность нужных драйверов для двух кандидатов, а не выбирают по моде.
Примеры из каталога ChipBaza
NUCLEO-F446RE — отладочная плата на MCU STM32F446, подходящая для сравнения bare-metal и RTOS-проектов на одном аппаратном стенде. FRDM-MCXA346 — пример другой экосистемы MCU и SDK. Плата разработки не равна микросхеме для серийного BOM: перед переносом проверяются точный MCU, доступная память, корпус, температурный диапазон и способ программирования.
Каталожные позиции полезны для прототипа, но архитектура ПО не должна зависеть от случайно установленной на плате периферии. Требования фиксируют на уровне интерфейсов и ресурсов.
Типовые ошибки
- добавлять RTOS, чтобы скрыть блокирующие драйверы;
- назначать почти всем задачам высокий приоритет;
- выделять stack без измерения high-water mark;
- передавать указатель на буфер без правил владения;
- выполнять форматирование и запись Flash в ISR;
- кормить watchdog из независимого таймера;
- путать среднюю загрузку с worst-case latency;
- обновлять ядро и библиотеки без фиксированного regression-набора.
Чек-лист архитектурного решения
- перечислены события, периоды, дедлайны и worst-case execution time;
- определено, какие операции могут блокироваться;
- рассчитаны RAM, stack, heap, DMA и сетевые буферы;
- описаны приоритеты, владельцы периферии и обмен сообщениями;
- включены assertions, stack protection, watchdog и trace;
- проверены sleep, wake-up latency и энергопрофиль;
- определены secure update, recovery и политика версий;
- выбранная архитектура испытана на реальной нагрузке.
Источники для технической проверки
Параметры и ограничения сверяйте с актуальной документацией производителя для полного артикула и нужного исполнения.
Следующий шаг
Проверьте артикулы и количество до отправки заявки
Загрузите спецификацию в BOM-сервис или пришлите полный код производителя менеджеру. Если точное совпадение не доказано, позиция останется на ручной проверке.