Содержание
- Из чего на самом деле состоит IoT-проект
- Выбор микроконтроллера: STM32 или ESP32
- RTOS или bare-metal
- Связь: какой протокол и какой канал
- OTA: обновление прошивки «в поле»
- Безопасность IoT с самого начала
- Edge или облако: где считать
- Типичные грабли и сроки
- Что важно при заказной embedded-разработке
- FAQ
Embedded-проект коварен тем, что выглядит обманчиво просто. «Датчик, который шлёт показания в облако» на словах — задача на вечер, а на деле это пять разных дисциплин, сшитых вместе: схемотехника, прошивка на C, радиосвязь, бэкенд и эксплуатация устройств, до которых после установки физически не дотянуться. Ошибка на любом из этих слоёв превращается в выезд монтажника или партию «кирпичей» на складе.
Эта статья — практический разбор того, как устроен заказной embedded/IoT-проект целиком: из каких слоёв он собирается, как выбрать микроконтроллер, когда нужна RTOS, как организовать связь и обновления и где проходит граница между edge и облаком. Без академизма — с упором на решения, которые потом дорого менять. Мы в Новакоме делаем такие проекты под ключ на стеке от голого железа до серверной части, поэтому говорим о граблях, на которые наступали.
Из чего на самом деле состоит IoT-проект
Полноценное подключённое устройство — это четыре слоя, и каждый накладывает ограничения на соседний. Спроектировать их по отдельности нельзя: выбор радиомодуля диктует энергобюджет, энергобюджет диктует микроконтроллер, микроконтроллер диктует, влезет ли в него TLS и OTA.
- Железо. Микроконтроллер, питание (батарея/PoE/сеть), датчики и исполнительные механизмы, радиоинтерфейс, антенна. Здесь же решается, что устройство будет жить пять лет от одной батарейки — или висеть на постоянном питании.
- Прошивка. Код на C/C++, работа с периферией через регистры и HAL, драйверы датчиков, логика, сетевой стек, bootloader. Это сердцевина проекта и обычно самая трудоёмкая часть.
- Связь. Транспорт (Wi-Fi, BLE, LTE/NB-IoT, LoRaWAN, Ethernet) и прикладной протокол (чаще всего MQTT). Здесь решается, сколько данных и как часто устройство передаёт и переживёт ли оно потерю связи.
- Edge/облако. Серверная часть: приём телеметрии, хранение, правила, дашборды, управление устройствами и выкатка обновлений. Иногда часть логики уезжает на шлюз рядом с устройствами — это и есть edge.
Ключевой принцип: проектируйте сверху вниз по требованиям, а собирайте снизу вверх. Сначала определите, что устройство должно делать, с какой автономностью и в каких условиях, — и только потом подбирайте железо, которое в эти требования укладывается. Самая частая причина переделок — когда микроконтроллер выбрали «потому что под него есть пример с мигающим светодиодом», а через два месяца выяснилось, что в нём не хватает флеша на две банки прошивки для OTA.
Выбор микроконтроллера: STM32 или ESP32
Два самых ходовых семейства в коммерческих проектах — STM32 (ядра ARM Cortex-M от STMicroelectronics) и ESP32 (Xtensa/RISC-V от Espressif со встроенным Wi-Fi и Bluetooth). Это не «лучше/хуже», а два разных инструмента под разные задачи. Развёрнутое сравнение мы дали в отдельном материале — STM32 vs ESP32 для IoT; здесь — короткая выжимка для принятия решения.
| Критерий | STM32 (Cortex-M) | ESP32 |
|---|---|---|
| Беспроводная связь | Нет на борту, нужен внешний модуль | Wi-Fi + BLE встроены |
| Энергопотребление | Очень низкое в sleep, предсказуемое | Выше, особенно при активном Wi-Fi |
| Линейка и масштаб | Огромная: от L0 до H7, легко мигрировать вверх/вниз | Узкая, но закрывает типовой IoT |
| Периферия и точность | Богатая, промышленные таймеры/АЦП | Достаточная для большинства задач |
| Цена за узел | Чип дешевле, но плюс радиомодуль и обвязка | Один чип закрывает связь и логику |
| Экосистема | STM32CubeMX/HAL, профессиональный инструментарий | Arduino/ESP-IDF, быстрый старт |
| Когда брать | Промышленность, батарейное питание, точное управление, сертификация | Wi-Fi-устройства, прототипы, «умный дом», быстрый time-to-market |
Грубое правило: нужен Wi-Fi/BLE и быстрый запуск — берите ESP32; нужны жёсткий энергобюджет, промышленная периферия, предсказуемость и запас на масштабирование линейки — STM32. На ESP32 один чип закрывает и логику, и связь, и плата получается дешевле и проще. На STM32 вы доплачиваете за внешний радиомодуль, но получаете микроамперы в сне (критично для устройств на батарейке), богатые таймеры и АЦП и возможность пересесть на более старший или младший кристалл того же семейства почти без переписывания кода.
Отдельно стоит сказать про «загрузить и забыть». Базовая работа с STM32 — это вход в режим загрузчика и заливка прошивки по UART/SWD (на отладочных платах вроде Blue Pill это делается перемычкой BOOT0 и линиями UART/RESET). На прототипе это удобно, но в серийном изделии вы не будете дёргать перемычки — там нужен нормальный bootloader и OTA, о которых ниже.
// STM32 HAL: «мигаем светодиодом» — канонический первый тест платы,
// который заодно проверяет тактирование и распиновку перед реальной логикой
int main(void) {
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef led = {
.Pin = GPIO_PIN_13,
.Mode = GPIO_MODE_OUTPUT_PP,
.Speed = GPIO_SPEED_FREQ_LOW,
};
HAL_GPIO_Init(GPIOC, &led);
while (1) {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(1000); // период 1 с
}
}
Важная оговорка про команду: уверенный embedded-разработчик не привязан к одному семейству. Знание C на уровне указателей и адресной арифметики, понимание периферии и умение «поднять» незнакомый микроконтроллер — заставить его стартовать и работать — ценнее, чем зазубренная распиновка конкретной платы. Поэтому при выборе подрядчика смотрите не на «знаем ли мы STM32», а на способность осознанно выбрать и освоить нужный кристалл под задачу.
RTOS или bare-metal
Второй фундаментальный выбор после железа — архитектура прошивки. Здесь два полюса.
Bare-metal (суперцикл). Один бесконечный while(1), в котором по очереди опрашивается периферия, плюс прерывания для срочных событий. Просто, прозрачно, минимум накладных расходов и оперативки. Идеально, когда задач немного и они слабо связаны: считал датчик — отправил — заснул.
RTOS (FreeRTOS, Zephyr и др.). Появляется планировщик и понятие задач (тасков) с приоритетами, между которыми распределяется процессорное время. Это нужно, когда в устройстве одновременно происходит несколько слабо синхронных вещей: тикает сетевой стек, опрашиваются датчики, обрабатывается дисплей, идёт OTA. На суперцикле такое быстро превращается в нечитаемого спагетти-монстра с ручным таймингом.
Эвристика простая. Одна-две независимые задачи и жёсткий энергобюджет — bare-metal. Сетевой стек (Wi-Fi/TCP) плюс несколько параллельных процессов — RTOS. Как только в проекте появляется полноценный TCP/IP или BLE-стек, вы де-факто уже в мире RTOS, потому что эти стеки сами построены на задачах. Отдельный водораздел — FreeRTOS против Zephyr: первый — лёгкий планировщик, второй — почти «ОС» с драйверами, сетью и системой сборки. Подробно мы разобрали это в материале Zephyr vs FreeRTOS.
// FreeRTOS: типичная развязка «опрос датчика» и «отправка» через очередь.
// Задачи не блокируют друг друга и имеют разные приоритеты.
static QueueHandle_t sensorQueue;
static void vSensorTask(void *arg) {
for (;;) {
int32_t value = sensor_read(); // блокирующее чтение датчика
xQueueSend(sensorQueue, &value, 0);
vTaskDelay(pdMS_TO_TICKS(1000)); // раз в секунду
}
}
static void vUplinkTask(void *arg) {
int32_t value;
for (;;) {
if (xQueueReceive(sensorQueue, &value, portMAX_DELAY) == pdTRUE) {
mqtt_publish("telemetry/temp", value); // отправка, когда есть данные
}
}
}
Главная ошибка новичков в RTOS — относиться к таскам как к бесплатным потокам и плодить их десятками. Каждый таск — это отдельный стек в дефицитной оперативке, и каждое разделяемое состояние требует синхронизации (очереди, мьютексы, семафоры). RTOS не отменяет дисциплину — она её требует.
Связь: какой протокол и какой канал
Связь в IoT — это два независимых решения: физический канал и прикладной протокол.
Канал выбирается по триаде «дальность — энергия — объём данных». Wi-Fi даёт толстый канал, но прожорлив (на ESP32 пик потребления — именно радио). BLE — короткие дистанции и малый расход, хорош для носимых и локальных устройств. LoRaWAN — километры дальности при копеечном энергобюджете, но единицы байт на сообщение. NB-IoT/LTE-M — сотовая связь там, где нет своей инфраструктуры. Ethernet/PoE — стационарные промышленные узлы, где питание и так есть.
Прикладной протокол. В подавляющем большинстве сценариев это MQTT — лёгкий publish/subscribe-протокол поверх TCP, спроектированный ровно под ненадёжные каналы и слабые устройства. Реже — HTTP/REST (проще, но тяжелее и без серверного push) или CoAP для совсем экзотических случаев. Когда выбирать что — мы разобрали в MQTT vs HTTP для IoT. Практический дефолт: телеметрия и команды — MQTT, разовые запросы и интеграции — HTTP.
Что важно заложить в прошивку с самого начала, независимо от протокола:
- Устройство теряет связь — это норма, а не исключение. Очередь неотправленных сообщений, экспоненциальный backoff при переподключении, буфер на флеше — без этого первый же провал сети превращается в потерю данных.
- Размер сообщений считается в байтах. На батарейном устройстве каждая лишняя передача — это минуты жизни. JSON удобен на сервере, но на узком канале часто выгоднее компактный бинарный формат.
- Идемпотентность команд. Если устройство переслало команду из-за обрыва, сервер не должен выполнить её дважды.
OTA: обновление прошивки «в поле»
OTA (Over-The-Air обновления) — это то, что отличает прототип от продукта. Пока устройство одно и лежит на столе, прошить его по проводу не проблема. Когда их тысяча и они размазаны по объектам, единственный способ исправить баг или закрыть уязвимость — обновление по воздуху. И закладывать его нужно в архитектуру до первой отгрузки, а не прикручивать потом.
Базовая безопасная схема выглядит так:
- Две банки прошивки (A/B) во флеше. Новый образ пишется во вторую банку, пока работает первая. Поэтому при выборе микроконтроллера сразу считайте флеш с запасом ×2 на код плюс место под загрузчик.
- Bootloader проверяет образ. Перед переключением — контроль целостности (CRC/хеш) и подписи. Прошивка без валидной подписи не должна стартовать в принципе.
- Атомарное переключение и откат. Новый образ помечается «пробным», устройство стартует с него и подтверждает работоспособность; если не подтвердило (завис, не вышел на связь) — bootloader откатывается на старую банку. Это страховка от «кирпича».
Без отката любое неудачное обновление в поле = выезд к устройству или потеря узла. Подробно архитектуру, подпись образов и стратегии раскатки на парк устройств мы разобрали в OTA-обновлениях прошивок. Главный тезис: OTA — это не фича, а несущая конструкция, потому что именно через неё вы потом будете чинить всё остальное.
Безопасность IoT с самого начала
История IoT — это во многом история чужих ботнетов. Mirai собрал армию из IP-камер и роутеров с дефолтными логинами и паролями и положил половину американского интернета. Уязвимости в одном Wi-Fi SDK (Realtek) разом затронули под миллион устройств шести десятков вендоров и жили в кодовой базе больше десяти лет. Вывод не в том, что «IoT небезопасен», а в том, что безопасность нельзя добавить в конце — её закладывают в железо и прошивку с первого дня.
Минимальный набор, который должен быть в любом серийном устройстве:
- Никаких дефолтных и зашитых паролей. Уникальные ключи на устройство, обязательная смена при вводе в эксплуатацию. Именно дефолтные пароли кормили Mirai.
- Шифрованный транспорт (TLS). Заранее проверьте, что выбранный микроконтроллер тянет TLS по флешу и оперативке, — на младших кристаллах это не данность.
- Подписанная прошивка и secure boot. Устройство выполняет только код, подписанный вашим ключом, — это закрывает и подмену по OTA, и атаки на загрузчик.
- Минимум открытой поверхности. Отключённые отладочные интерфейсы (JTAG/SWD) в продакшене, закрытые порты, никаких «временных» бэкдоров.
- Канал обновлений как часть защиты. Без OTA вы не сможете закрыть уязвимость, которую найдут после отгрузки, — а её найдут.
Системно угрозы и контрмеры удобно сверять по OWASP IoT Top 10 — это рабочий чек-лист на этапе проектирования, а не аудит постфактум. Дешёвое правило: пройдитесь по нему до того, как развели плату.
Edge или облако: где считать
Классическая схема «датчик шлёт всё в облако, облако думает» работает не всегда. Когда устройств много, а данные объёмные (видео, вибрация, поток с десятков датчиков), гнать всё наверх дорого по трафику и медленно по реакции. Тогда часть вычислений переезжает ближе к источнику — это edge computing: считаем на месте, а наверх отдаём только результат или агрегаты.
Edge оправдан, когда есть хотя бы одно из:
- Жёсткая задержка. Реакция нужна за миллисекунды — ждать round-trip до облака нельзя (управление, безопасность).
- Дорогой или узкий канал. Передавать сырьё накладно; дешевле обработать и отправить сводку.
- Автономность. Устройство должно продолжать работать при обрыве связи с облаком.
- Приватность и регуляторика. Сырые данные не должны покидать периметр.
Тренд последних лет — даже инференс нейросетей уезжает на edge: на относительно скромных ядрах уже крутятся компактные модели, и «считать на месте, отдавать готовый результат» становится массовым паттерном. Это снимает нагрузку с серверов и убирает зависимость от канала.
Облако при этом никуда не девается — оно остаётся местом, где хранится история, обучаются модели, живут дашборды и управление парком. На практике почти всегда получается гибрид: edge-шлюз делает быструю локальную обработку и буферизацию, а облако (или IoT-платформа вроде ThingsBoard) отвечает за визуализацию, правила, хранение и OTA. Вопрос не «edge или облако», а где провести границу — и это проектное решение, которое зависит от данных и требований к задержке.
Типичные грабли и сроки
Чаще всего embedded-проекты буксуют не на алгоритмах, а на банальных, но дорогих вещах:
- Недооценка железного цикла. Плата разводится, заказывается, едет, в ней находится ошибка — и круг повторяется. Каждая итерация железа — это недели, а не часы как в вебе. Закладывайте ревизии заранее.
- Не тот микроконтроллер. Не хватило флеша на OTA, оперативки на TLS, ножек на периферию. Переезд на другой кристалл в середине проекта — это переписанные драйверы и новая плата.
- Энергобюджет «по факту». Устройство, которое в ТЗ живёт год от батарейки, в реале садится за месяц, потому что радиомодуль не уходил в сон. Энергопотребление измеряют, а не считают на бумаге.
- OTA «потом». Прикрутить обновления к готовой прошивке без A/B-банок и отката — почти всегда означает переделку bootloader и разметки флеша.
- Тестирование на одном экземпляре. Прошивка, идеально работающая на столе, ведёт себя иначе на сотне устройств с реальной радиообстановкой, разбросом компонентов и слабым питанием.
По срокам ориентир для типового устройства средней сложности: несколько недель на прототип на отладочной плате, дальше итерации железа и прошивки параллельно, и реально работающее серийное изделие с OTA и безопасностью — это месяцы, а не недели. Основное время съедают не «фичи», а доведение до надёжности: поведение при сбоях связи, при разряде, при кривых данных.
Что важно при заказной embedded-разработке
Если вы заказываете embedded/IoT-разработку на стороне, на что смотреть в первую очередь:
- Команда закрывает все слои. Хорошо, когда схемотехника, прошивка, связь и серверная часть — это одна ответственность, а не три подрядчика, кивающих друг на друга на стыках. Большинство сложных багов живёт именно на границах слоёв.
- OTA и безопасность — в ТЗ с первого дня, а не «добавим в следующей версии». Их ретрофит стоит дороже, чем закладка.
- Право на исходники и тулчейн. Вы должны иметь возможность собрать прошивку без исходного подрядчика. Привязка к закрытому билду — это риск, сопоставимый с потерей доступа к устройствам.
- Тестовый стенд и измеримые критерии. Энергопотребление, поведение при потере связи, успешность OTA на парке — это проверяемые метрики, а не «работает же».
- Серверная часть — это полноценный бэкенд. Приём телеметрии, очереди, хранение, управление устройствами — нормальная инженерия со своими требованиями к надёжности. У нас эта часть обычно живёт на Java/Kotlin-стеке — см. разработку на Spring.
Embedded прощает меньше ошибок, чем веб: до устройства не дотянуться рукой, обновление рискованно, а баг может означать партию брака. Поэтому решения о железе, RTOS, связи и OTA принимаются в начале — и именно их цена ошибки максимальна.
FAQ
STM32 или ESP32 для нового проекта? Если нужен Wi-Fi/BLE и быстрый старт — ESP32, у которого связь на борту и плата проще. Если важны минимальное энергопотребление, промышленная периферия, точность и запас на масштабирование линейки — STM32 с внешним радиомодулем. Подробности — в сравнении STM32 vs ESP32.
Когда нужна RTOS, а когда хватит bare-metal? Одна-две независимые задачи и жёсткий энергобюджет — bare-metal (суперцикл). Несколько параллельных процессов, особенно сетевой стек Wi-Fi/TCP или BLE, — RTOS. Как только появляется полноценный сетевой стек, вы фактически уже в RTOS.
Можно ли добавить OTA в уже готовое устройство? Технически да, но обычно это означает переделку bootloader, разметки флеша под две банки и схемы отката. Поэтому OTA закладывают до первой отгрузки и сразу выбирают микроконтроллер с запасом флеша.
Что в IoT-безопасности самое критичное? Убрать дефолтные и зашитые пароли, включить TLS, подписывать прошивку (secure boot) и иметь рабочий канал обновлений, чтобы закрывать уязвимости после отгрузки. Именно дефолтные пароли и непропатченные SDK кормили крупнейшие IoT-ботнеты. Чек-лист — OWASP IoT Top 10.
Edge или облако — что выбрать? Это не «или». Edge берут, когда нужна низкая задержка, узкий/дорогой канал или автономность при обрыве связи; облако — для хранения, аналитики, дашбордов и управления парком. На практике почти всегда гибрид, и вопрос в том, где провести границу.
Если вы планируете embedded/IoT-устройство — от выбора микроконтроллера и прошивки до связи, OTA и серверной части — мы в Новакоме делаем такие проекты под ключ и закрываем все слои одной командой. Посмотрите наши услуги по разработке на Spring для серверной части IoT-платформы или напишите нам с описанием задачи и условий эксплуатации устройства.