Обычное дело: мы используем cookie. Здесь можно узнать зачем
Хорошо

Bare Metal или RTOS – что лучше для вашего устройства? Достоинства, недостатки и типовые архитектуры

Выбор между bare metal и RTOS влияет на стоимость проекта, сроки вывода продукта на рынок и риск технических долгов. В этой статье мы рассказываем о ключевых отличиях между bare-metal прошивкой и встроенным ПО на операционных системах реального времени. Так разбираем типовые архитектуры, применяемые в обоих типах ПО, и приводим в качестве примеров реальные проекты.
Если к встроенному устройству предъявляются жесткие требования по времени реакции на события, то его прошивку можно реализовать как программу без операционной системы (bare metal) или как приложение на операционной системе реального времени (RTOS). Правильный выбор между bare metal и RTOS на старте определяет не только программную архитектуру ПО, но и экономику всего проекта. От этого зависят стоимость “железа” и лицензий, а также сроки вывода продукта на рынок и будущие расходы на поддержку. Чтобы принимать такие решения не вслепую, а опираясь на опыт реализованных проектов, свяжитесь с нашей командой для консультации или для полноценного старта разработки.

Непродуманный выбор может значительно усложнить проект. Например, вы можете получить избыточно сложную программу на RTOS там, где хватило бы простого суперцикла. Или наоборот, bare‑metal систему, которую придется дорого переделывать, когда требования по функционалу, масштабируемости и надежности вырастут. В этой статье мы разбираем ключевые различия между bare metal и RTOS, их типовые архитектуры и примеры проектов из нашей практики.

Ключевые свойства Bare Metal

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

Если в программе не предусмотрено большого количества взаимозависимых задач, то bare metal выгодно отличается от RTOS предсказуемостью без планировщика задач, простотой отладки, более низким потреблением ресурсов и энергии. Последнее позволяет использовать более простые и дешевые микроконтроллеры. Однако по мере усложнения приложения его становится труднее разрабатывать, отлаживать, поддерживать и масштабировать.

Преимущества
  • Минимальные накладные расходы (overhead);
  • Низкие требования к ресурсам;
  • Прозрачные задержки: нет скрытых фоновых задач;
  • Быстрая загрузка: минимум инициализационного кода.

Недостатки
  • Сложно масштабировать: код быстро превращается в “спагетти”;
  • Нет готовых инструментов и сервисов, приходится использовать самописные или интегрировать сторонние библиотеки;
  • Ограниченная многозадачность.
Bare-metal прошивка обычно создается для небольших и простых устройств, которые не требуют многозадачности или сложного управления ресурсами: контроллеров двигателей постоянного тока, термостатов, реле, простых контроллеров освещения, клавиатурных контроллеров и т.д. Разработка встроенного ПО для таких систем на RTOS была бы излишне сложной, что увеличило бы сроки и стоимость проекта, а также себестоимость самого прибора.

Типовые архитектуры bare-metal прошивки

Ниже мы рассмотрим типовые архитектуры встроенного ПО без операционной системы. Стоит оговориться, что в чистом виде они применяются редко. Обычно в реальной программе используют элементы разных архитектур, усложняя структуру ПО по мере необходимости.

  1. Суперцикл

Это простейшая программная архитектура. Вся логика ее работы выполняется внутри бесконечного цикла. Микроконтроллер по очереди опрашивает входы, считывает, обрабатывает и записывает данные, обновляет состояние, управляет выходами и вызывает нужные функции. По завершении итерации алгоритм запускается заново.
Схема работы суперцикла
Плюсы
  • Легко писать с нуля: нет сложной логики или параллельных процессов.
  • Разработчик сохраняет полный контроль над таймингами: выполнение кода не прерывается не прописанными в нем операциями.
  • Не нужно распределять аппаратные ресурсы: процесс всегда один.
  • Минимальный overhead (затраты ресурсов на служебные операции) и требования к Flash- или RAM-памяти.
  • Программы с такой архитектурой получаются маленькими и понятными.

Минусы
  • Плохо поддается масштабированию. С добавлением все новых задач код увеличивается, в цикле растет задержка.
  • По мере разрастания код становится неструктурированным, запутанным и трудночитаемым, что усложняет поддержку и отладку.

2. Суперцикл с прерываниями

Если чистого суперцикла недостаточно для выполнения нужных функций, в прошивке можно использовать прерывания. В такой архитектуре часть функций выполняет главный бесконечный цикл, а частьобработчики прерывания.
Схема работы суперцикла с прерываниями
Цикл все так же последовательно выполняет основную логику, а асинхронные или наиболее критичные по времени аппаратные события не опрашиваются циклом, а вызывают обработчики прерываний. Прерывание останавливает работу основного цикла (контекст всех регистров, которые были использованы в этот момент, сохраняется), запускается обработчик прерывания. Он выполняет нужные вычисления, записывает результат, и основной цикл возобновляется.

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

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

3. Событийная система

Это архитектура, основой работы которой становится не последовательный проход по жестко “прошитому” списку действий в суперцикле, а события.
Схема работы событийной системы
В системе определяют набор событий – “пришел байт по UART”, “готов резльтат АЦП”, “нажата кнопка” и т.п. При возникновении события аппаратные прерывания формируют объект или код события и помещают его в очередь. В главном цикле или в отдельном обработчике работает диспетчер событий. Он извлекает из очереди событие, проверяет наличие подписчиков на него и, если они есть, вызывает соответствующий обработчик. Тот обрабатывает событие и возвращает контроль диспетчеру. Процесс продолжается, пока очередь не опустеет.

Плюсы
  • Можно реализовать сложную логику с большим количеством функций. Но программа все еще “легче”, чем аналогичная с операционной системой, а требования к аппаратной части ниже.
  • Микроконтроллер “просыпается” только по событию, а не крутит суперцикл впустую. Это снижает энергопотребление и латентность реакции на важные сигналы.
  • Легче масштабировать, чем суперцикл с прерываниями, просто добавляя события и соответствующих подписчиков. Обработчики событий можно писать как слабо связанные друг с другом компоненты.

Минусы
  • Сложнее с точки зрения отладки.
  • При масштабировании становится труднее отслеживать взаимодействия обработчиков событий, чтобы не допускать взаимоисключающих процессов.
  • На чисто событийной системе сложнее реализовать параллельные процессы.

4. Архитектура на конечных автоматах

Конечный автомат, или машина состояний, (Finite State Machine, или FSM) – это модель, в которой система в каждый момент времени находится в одном из заранее ограниченного набора состояний – например, “выключен”, “простой”, “запуск”, “ошибка”. При получении определенных сигналов или событий (нажатии кнопки, получении байта, истечении таймера) машина переходит в другое состояние. Переход осуществляется по заранее прописанным правилам, которые определяют, из какого состояния в какое перейти при данном событии и какие действия при этом выполнить.
Схема машины состояний
Конечные автоматы нужны там, где логика работы устройства уже выходит за рамки “линейного” суперцикла. Если попытаться реализовать тот же функционал в рамках суперцикла, то код быстро превратится в лапшу if/else и флагов: “если нажата кнопка и мы уже подключены, но не в режиме обновления, а еще второй справа тумблер включен, то…” Это только увеличит сроки проекта и создаст много проблем на этапе сопровождения.

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

Плюсы
  • Прозрачность кода: все возможные состояния устройства и переходы между ними описаны явно.
  • Поведение устройства предсказуемо: вместо размытых проверок по множеству флагов для каждого состояния можно задать явные и гарантированные реакции на события.
  • Вместо переплетения условий в суперцикле разработчик описывает режимы работы прибора как переходы между состояниями. Это упрощает логику кода.
  • Упрощает масштабируемость: достаточно добавить новое состояние и переходы.

Минусы
  • Добавлять режимы до бесконечности нельзя. При увеличении числа состояний и переходов логику становится трудно понимать и изменять.
  • Если изначально автомат проектировался под простые сценарии, а потом логика сильно усложнилась, структуру автомата приходится переделывать с нуля.
  • Непрерывные вычисления, сложные алгоритмы обработки сигналов, фильтрация, оптимизация и т.п. плохо ложатся на эту архитектуру, если она реализована в чистом виде. Поэтому может потребоваться добавлять отдельные модули с “традиционным” кодом.

5. С применением планировщика задач

Планировщик задач – это часть программной логики, которая распределяет процессорное время между различными процессами (программами, скриптами, командами) в заданное время.
Схема работы планировщика задач
Планировщики есть во многих операционных системах в качестве встроенных сервисов. Если же мы разрабатываем bare-metal прошивку, то такой сервис можно написать самому.

Плюсы
  • Планировщик дает “легкую” многозадачность и управляемое распределение времени между частями логики. Он позволяет четко определить, какие задачи важнее, вместо неявного управления через порядок if‑ов и длину итерации суперцикла.
  • Наличие планировщика роднит прошивку с RTOS, но требования к аппаратной платформе остаются невысокими.
  • Самописный планировщик может содержать всего несколько десятков строк кода, а разработчик может заложить ровно те правила планирования, которые нужны конкретной системе без лишних абстракций и универсальности полноценной RTOS.

Минусы
  • С увеличением числа задач и требований к таймингам логика планировщика быстро усложняется.
  • Нет готовых механизмов синхронизации. Семафоры, очереди, события, мьютексы, протоколы приоритетов – все приходится писать с нуля, что увеличивает сроки разработки.
  • Большинство самописных планировщиков используют кооперативную модель многозадачности, при которой задача обязана самостоятельно возвращать управление. В такой архитектуре одна некорректно реализованная, зависшая или вычислительно тяжелая задача способна полностью заблокировать выполнение остальных.

Пример bare-metal прошивки: графический калькулятор

Инженер КЕДР Solutions вскрывает корпус разработанного компанией графического калькулятора.
В качестве примера разработки bare-metal прошивки приведем наш проект графического калькулятора. Это достаточно простое устройство, в котором нет большого количества сложных и параллельных задач. Сама логика его работы отлично ложится на парадигму суперцикла. Написание встроенного ПО на RTOS было бы излишне трудозатратным и замедлило бы проект. Выбор bare metal позволил ускорить работу и облегчить отладку. В результате проект потребовал меньше переделок, что снизило стоимость разработки.

Почти весь функционал калькулятора представляет собой повторяющиеся задачи, которые реализованы в суперцикле. При запуске микроконтроллер настраивает периферию. В основном цикле устройство сбрасывает сторожевые таймеры, обновляет состояние светодиодов, опрашивает модуль измерения уровня заряда батареи. Большую часть времени микроконтроллер остается в режиме ожидания для экономии батареи. Раз в 1 мс он просыпается и повторяет основной цикл. В нем же выполняется “математическая” логика.

Две задачи в прошивке вызываются по времени, используя аппаратный таймер на микроконтроллере. Раз в 10 мс устройство опрашивает клавиатуру. При регистрации нажатия программа обновляет экран калькулятора, чтобы отобразить на нем изменения. В данном случае было проще и надежнее реализовать регистрацию нажатий через опрос: скорость МК позволяла не бояться задержек. Кроме того, раз в 33 мс микроконтроллер обновляет экран независимо от того, были ли нажаты какие-либо клавиши.

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

Кроме того, работа с USB реализована через прерывание. Когда по USB приходит пакет данных, вызывается обработчик, который складывает пакет в специальный статический буфер. Сам буфер обрабатывается в основном цикле, что позволяет быстро освободить USB для приема следующего пакета. Протокол взаимодействия с ПК синхронный, что позволяет избежать переполнения приемного буфера USB.

Если вы обращаетесь к команде со своим проектом, важно еще на старте обсудить возможность миграции на новые аппаратные платформы. Приложения на RTOS переносить легко, но в bare-metal прошивке такую возможность необходимо предусмотреть заранее.

Так, когда проект графического калькулятора начинался, в качестве микроконтроллера мы выбрали GD32F470. На тот момент он представлял из себя наилучшее соотношение цены и качества. Однако функционал калькулятора с тех пор значительно расширился, и сейчас на нем не хватает памяти. GD32 с нужными нам характеристиками отсутствует в продаже, поэтому мы обсуждаем с заказчиком миграцию на STM32. Такую возможность мы предусмотрели еще на старте проекта, поэтому разделили встроенное ПО устройства на две части. Одна отвечает за бизнес-логику, а другая – за работу с аппаратным обеспечением. Таким образом, для миграции на новый МК достаточно переписать лишь ту часть, которая отвечает за работу с “железом”. Такая архитектура также позволяет без проблем поддерживать обе версии прибора, а также реализовать эмулятор графического калькулятора на ПК и Web.

Ключевые свойства встроенного ПО на RTOS

Операционные системы реального времени (RTOS) – это специализированные ОС, созданные отвечать жестким временным ограничениям встроенных устройств. Прошивка с RTOS использует ресурсы операционной системы для планирования и синхронизации задач, а также взаимодействия с аппаратным обеспечением через драйверы и API.

Такое встроенное ПО требует больше аппаратных ресурсов и отличается большим энергопотреблением. У некоторых микроконтроллеров недостаточно памяти, чтобы вместить в себя приложение на RTOS. Однако использование ОС значительно облегчает и ускоряет разработку встроенного ПО, если речь идет о сложной программе, призванной выполнять параллельно несколько задач. Благодаря ее инструментам разработчику проще писать и отлаживать код и масштабировать решение.

Преимущества
  • Поддержка многозадачности;
  • Модульность и масштабируемость;
  • Предсказуемая работа в реальном времени при высокой сложности;
  • Готовые инструменты и сервисы.

Недостатки
  • Более высокое потребление ресурсов;
  • Требует от разработчика более высокой квалификации;
  • Избыточность для простых задач.
RTOS подходит для проектирования электроники с несколькими одновременно работающими подсистемами и строгими, но при этом управляемыми требованиями по времени. Прошивка на RTOS обычно пишется для промышленных контроллеров, робототехники, автомобильной и транспортной электроники, медицинских приборов, “умных” устройств и т.д.

Типовые архитектуры прошивки на RTOS

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

1. Многопотоковая реализация

Схема многопотоковой реализации программного обеспечения
Это классическая программная архитектура, которая позволяет выгодно применить многозадачность RTOS. Приложение делится на несколько потоков исполнения (tasks/threads) – например, отдельный поток для работы с сетью, поток для обработки датчиков, поток для пользовательского интерфейса и т.д. А ядро ОС по своим правилам решает, какой поток работает в данный момент. Ядро RTOS хранит их контексты (регистры, указатели стека) и по таймерам или событиям переключается между ними, выбирая те, что готовы к исполнению, и отдает CPU тому, у кого выше приоритет.

В самом простом исполнении потоки минимально зависят друг от друга. Для потокобезопасной работы используются встроенные инструменты ОС – мьютексы, симафоры, очереди, события. Они помогают распределить ресурсы и данные между потоками.

Плюсы
  • Легко масштабировать, просто добавляя новые потоки.
  • Каждый поток представляется практически отдельной программой. Код становится модульным, и его легче сопровождать.
  • Механизмы взаимодействия между частями системы уже встроены в RTOS.

Минусы
  • Повышается сложность проектирования. Нужно продумывать приоритеты, взаимодействие задач, избегать взаимных блокировок, инверсии приоритетов и прочих классических “болей” многопоточности. Иначе мы рискуем получить состояние гонки, когда несколько потоков одновременно получают доступ к одним и тем же ресурсам без корректной синхронизации.
  • В многозадачной системе часто проявляются гонки, дедлоки и тайминговые баги. Однако отловить их непросто, что усложняет отладку.
  • Как и любая другая архитектура на RTOS, эта требует больше аппаратных ресурсов, чем bare metal.

2. Обмен сообщениями через очереди

Схема работы обмена сообщениями в ПО
Эта архитектура похожа на событийную модель. Задачи начинают “разговаривать” через сообщения. Задача‑producer формирует сообщение (структуру с данными или командой) и кладет его в очередь. Задача‑consumer блокируется в ожидании сообщения, просыпается, когда оно приходит, и обрабатывает его.

Обмен данными настраивается с помощью готовых примитивов RTOS: блокирующего ожидания, таймаутов, приоритетной обработки, размера очереди. Это позволяет аккуратно управлять потоком данных и нагрузкой.

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

Минусы
  • Растет сложность. Нужно продумывать форматы сообщений, кто кому что шлет, какие очереди существуют, как обрабатывать ошибки и переполнение.
  • Выше накладные расходы по памяти и времени. Очередям нужен буфер – иногда немалый, если сообщения крупные.
  • В маленьких системах, где есть 2–3 задачи и простая логика, архитектура с обменом сообщениями будет избыточно сложной.

3. С использованием прерываний

RTOS также позволяет работать с аппаратными прерываниями. Как и в случае с подобной архитектурой на bare metal, здесь программа реагирует на аппаратные события максимально быстро, а “тяжелая” логика выполняется уже в задачах ОС. Аппаратное событие генерирует прерывание. Процессор приостанавливает текущую задачу и выполняет короткий обработчик прерывания. После выхода из обработчика планировщик RTOS решает, какую задачу запустить дальше.

Плюсы
  • Минимально возможная задержка реакции на внешние события. Задачи можно разделить на критичные по времени и более “тяжелые”, но менее критичные.
  • В такой архитектуре объединяются быстрота и аппаратная реакция прерываний, а также структурированность и многозадачность RTOS.

Минусы
  • Сложность разработки и отладки повышается. Нужно аккуратно выбирать, какие задачи должны реагировать на прерывания, т.к. “тяжелые” прерывания будут приводить к нестабильным задержкам и пропускам событий.
  • Большое количество часто срабатывающих прерываний увеличивает overhead на вход/выход из обработчика и контекстные переключения задач. При неквалифицированном дизайне это может “съедать” значительную долю процессорной мощности.

4. Событийные системы

Современные операционные системы реального времени также дают разработчику инструментарий для построения кода на событийной архитектуре. Вместо постоянного опроса состояний каждая задача ждет событие – сигнала, флага, сообщения в очереди, семафора от другой задачи, таймаута от системного таймера. Когда событие наступает, задача “просыпается”, обрабатывает его (часто через конечный автомат) и снова переходит в режим ожидания.

Получается RTOS‑версия событийной системы, похожая по идее на bare metal, но распределенная по потокам.

Плюсы
  • Событийная архитектура на RTOS дает более “чистый” и эффективный способ реакции на множество условий одновременно по сравнению с другими.
  • Задачи блокируются в ожидании событий и не тратят ресурсы CPU на опрос множества флагов или очередей.
  • Удобное ожидание сразу нескольких условий.
  • Событийная система лучше масштабируется по числу событий и задач. Один набор событий может разруливать синхронизацию между многими задачами, фактически заменяя множество отдельных семафоров и уведомлений. Это уменьшает накладные расходы по памяти и вызовам ядра.
  • Такая архитектура проще ложится на модель конечных автоматов. Вместо “ручного” опроса множества признаков в суперцикле каждой задачи, система переходит в следующее состояние после прихода заданного события.

Минусы
  • Выше риск гонок и потери событий.
  • Требуется больше усилий для гарантии предсказуемости поведения и времени реакции системы.
  • Из‑за асинхронности и комбинирования событий усложняется отладка.
  • Ядро RTOS может использоваться неэффективно: много служебной логики вокруг событий, а типичные возможности планировщика и примитивов синхронизации остаются полузадействованными.
  • В гибридных системах возрастает риск архитектурной несогласованности: одна и та же подсистема сигнализируется разными способами, а поведение становится трудно предсказуемым.

Пример встроенного ПО на RTOS: ЭЭГ-система

Врач готовит пациентку к ЭЭГ-исследованию
Одним из проектов, в котором прошивка была реализована на RTOS, является разработка ПО для ЭЭГ-системы. Заказчик проектирует решения для регистрации электроэнцефалограммы. Он обратился в КЕДР Solutions с уже готовым аппаратным обеспечением и попросил написать для него прошивку в разумные сроки.

По замыслу заказчика, устройство должно было не только регистрировать ЭЭГ, но также передавать данные на планшет и принимать с него команды прямо во время исследования. Таким образом, система должна была одновременно выполнять несколько достаточно “тяжелых” задач. Важнейшие из них – обработка и сохранение данных ЭЭГ-исследования с аналого-цифрового преобразователя (АЦП), а также обмен данными по BLE с планшетом. Решение также подразумевало интенсивный обмен данными между различными задачами.

При таких вводных наилучшее решение – написать ПО на RTOS: она предоставляет инструменты для создания параллельных задач и средства их синхронизации. Это значительно ускоряет разработку встроенного ПО. В качестве операционной системы команда выбрала FreeRTOS – качественную свободно распространяемую ОС.

В основе архитектуры созданного ПО лежит многопотоковая реализация с добавлением прерываний, событий и обмена сообщениями. Так, задача по обработке данных с АЦП запускается, когда срабатывает аппаратное прерывание с АЦП. В этот момент сырые данные с преобразователя складываются в очередь, что, в свою очередь, выступает событием, которое запускает обработку и сохранение этих данных на microSD-карту. Перед завершением работы задача отправляет событие “данные записаны на SD-карту” в задачу, которая отвечает за взаимодействие с планшетом по BLE.

Пока первая задача “спит”, работает BLE – отправляет данные исследования на планшет в режиме реального времени или получает команды с него. Для хранения принятых по BLE пакетов также используется очередь. Например, если в очередь попадает пакет с командой “остановить исследование”, это событие запускает соответствующую задачу.

Заключение

В разработке встроенной электроники выбор между bare metal и RTOS — это вопрос не технологий, а контроля, сложности и масштаба системы.

Bare metal дает выигрыш в простоте, себестоимости и предсказуемости там, где логика относительно проста, а “железо” налагает жесткие ограничения. RTOS, напротив, раскрывает себя в более сложных системах с параллельными задачами, интенсивным обменом данными и повышенными требованиями к масштабируемости и сопровождению. Выбор между этими подходами стоит делать исходя из требований к функционалу, таймингам, ресурсам микроконтроллера и планам по развитию продукта. И здесь вам пригодится опыт нашей команды.

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