После 13 лет программирования микроконтроллеров размышляя на тему того, что должно быть в типовой микроконтроллерной прошивке я проанализировал сотни сборок и десятки электронных плат. В результате как в математике вынес за скобки базовый функционал, который так или иначе нужен практически в каждом проекте. Этот функционал кристаллизировался в требования, которые я решил назвать ортодоксально каноническая форма прошивки (ОКФП). По аналогии с тем как в С++ есть такое понятие, как ортодоксально каноническая форма для класса.
Итак обо все по порядку. Что же такое ортодоксально каноническая форма прошивки? Если коротко, то это компромисс между простотой и функциональностью.
Ортодоксально каноническая прошивка это прошивка, которая обладает следующими свойствами:
1--Прошивка собирается из GNU Make скриптов. Это необходимо для сборки по клику на *.bat скрипт. Плюс сборка из скриптов нужна для подключения сборки к серверу автоматического построения Jenkins.
2--Сборка без RTOS. Например, UART загрузчику RTOS нужна, как собаке бензобак. Потом прошивки с RTOS проблематично сертифицировать. Плюс NoRTOS код можно легко собирать и на LapTop PC в виде консольного приложения и тем самым быстро отлаживать всяческую математику программы. Поэтому безусловно надо научиться собирать проекты без RTOS и держать наготове сборки без RTOS.
3--В сборке присутствуют драйверы для следующих базовых фундаментальных аппаратных подсистем: Clock, MCO, PLL, NVIC, SysTick, GPIO, PINMUX, FLASH, TIMER, DMA, UART. Реализация драйверов должна быть полной.
4--В сборке присутствует HeartBeat LED. Чтобы просто глядя на устройство убеждаться, что прошивка не зависла. Раз мигает LED значит не зависло. Значит вертится суперцикл в main-е.
5--В прошивку добавлен драйвер аппаратных таймеров. Это необходимо не только для вычисления микросекундных пауз, но и для получения up-time программы. Для анализа времени исполнения участков кода и для диспетчера задач.
6--В сборке присутствует диспетчер задач на базе компонента Limiter.
7--В сборке присутствует UART-CLI.
8--В сборке присутствует NVRAM.
9--В сборке присутствует API для пуска модульных тестов.
10--Модульные тесты можно вызывать текстовой командой из UART-CLI буквально из PuTTY.
11--Также следует сразу подготовить отдельную сборку загрузчика через UART-CLI.
12--Должен быть запущен сторожевой таймер.
Вот, пожалуй, и всё. Всего лишь какие-то жалкие двенадцать пунктов. По факту только на этой почве и возможно полноценно начинать наращивать и отлажить какой бы то ни было прикладной функционал или приложение. А без этого минимума-минимумов будет не разработка, а стрельба из лука с завязанными глазами. Уж поверье мне... Нахлебался уже.
CLI, NVRAM и сборка из скриптов это норма. Эти атрибуты являются просто джентльменским набором программиста для абсолютно любой нормальной, современной, взрослой, промышленной прошивки. Своего рода коробочка в которую можно заложить абсолютно любой прикладной функционал. Это так же принято, как в нормальных государствах присутствует школьное образование, медицинское страхование и пенсионная система. Если у Вас в репозитории и прошивке всего этого добра нет, то, наверное, говорить о разработке какого-либо устройства просто даже не имеет смысла... Проект заглохнет, разрушится под собственным весом спустя два-три года. Разработка уйдет в штопор и пополнит кладбище не взлетевших проектов. Я сам это видел своими глазами до того как сам пришел к необходимости ОКФП. Как ни крути, но сначала надо поднять какую-никакую минималистическую систему. Писать прошивку без этих 7-10 свойств - это как ходить по улице без одежды. Понимаете?...
Более подробно по каждому требованию к ортодоксально канонической форме для прошивки можно почитать отдельные тексты по ссылкам в источниках
Название текста |
URL |
Зачем Программисту Микроконтроллеров Диофантовы Уравнения |
|
Как собрать Си программу в OS Windows |
|
NVRAM для микроконтроллеров |
|
Почему Нам Нужен UART-Shell? |
|
Архитектура Хорошо Поддерживаемого Программного Компонента |
|
Модульное Тестирование в Embedded |
|
Диспетчер Задач для Микроконтроллера |
|
Почему важно собирать код из скриптов |
|
23 Атрибута Хорошего Загрузчика |
|
Запуск сервера сборки Jenkins |
|
Что Должно Быть в Каждом FirmWare Pепозитории |
|
Архитектура Xорошего Кода Прошивки (Массив-Наше Всё) |
|
Aтрибуты Хорошей Прошивки (Firmware) |
Можно конечно и расширять этот список. Добавить требование запуска MPU, окраски стековой памяти, сборки из CMake и прочие радости. Однако тогда придется вводить какое-то новое следующее определение. Например, условно, "надежная прошивка" или "имунная прошивка" и т. п.
Разумеется в случае работы с Bluetooth или LwIP вам ещё потребуется какая-никакая RTOS. Это вообще отдельная тема. Но ОКФП у вас должна быть всегда наготове для экспериментов, испытаний и прогона модульных тестов.
Если есть, что добавить (или исключить) к требованиям к ОКФП, то пишите в комментариях.
Комментарии (37)

EmCreatore
07.12.2025 16:31Ось в современном embedded абсолютно необходима.
Ее осутствие говорит о том что система недоработана в плане масштабируемости, унифицированности и универсальности.
Поэтому некая "каноническая форма" никак не может быть без RTOS.
Без RTOS ни стек TСP/IP, ни Bluetooth, ни файловую систему ни что-то другое серьезное невозможно нормально интегрировать.
Все они так или иначе будут уворовывать ресурсы времени, которые без RTOS у них отобрать и поделить не получится.
Остальные пункты - вкусовщина.
Claude Opus за минуты может сделать инфраструктуру для компиляции хоть GNU хоть LLVM
И сорсы переделает под них.
Но реально на сегодня лучшие инструменты отладки имеют коммерческие тулсы типа IAR или Keil. Поэтому многие SDK от производителей чипов имеют варианты для IAR. И даже Zephyr уже имеет порт для IAR.
Сейчас писк моды - делать отладку через WEB интерфейс.
Поэтому "каноническая форма" должна обязательно иметь WEB сервер и хранилище WEB страниц. Потому что Claude Opus идеально генерит WEB интерфейс. С графиками, таблицами, формами, редакторами - всем чем хочешь.

checkpoint
07.12.2025 16:31Поэтому некая "каноническая форма" никак не может быть без RTOS. Без RTOS ни стек TСP/IP, ни Bluetooth, ни файловую систему ни что-то другое серьезное невозможно нормально интегрировать.
Вы сейчас действительно про Embedded приложения говорите ? Тогда понятно откуда у холодильников и СВЧ печей потребность в облачных сервисах. ;-)

EmCreatore
07.12.2025 16:31Да знаете ли, паровоз не ждёт пассажиров.
Не успели сделать IoT в своих девайсиках — сделают без вас.
И облака теперь тоже горячая тема.Особенно убедительно, когда приплетают холодильники и всякое такое в духе представлений прошлого века. Надеюсь, облака для пылесосов и счётчиков уже не шокируют?
А так вообще-то речь шла об отладке.
aabzel Автор
07.12.2025 16:31Особенно убедительно, когда приплетают холодильники и всякое такое
У меня холодильник без интернета. Даже даром такой не стал бы брать.

aabzel Автор
07.12.2025 16:31Без RTOS , ни файловую систему невозможно нормально интегрировать.
Как же я тогда LittleFs без RTOS на китайском МК запустил?
https://habr.com/ru/articles/925372/

aabzel Автор
07.12.2025 16:31Но реально на сегодня лучшие инструменты отладки имеют коммерческие тулсы типа IAR или Keil.
Не согласен. IAR - это IDE для школоты.
Вот пояснительная записка про вред GUI-IDE-шек
https://habr.com/ru/articles/794206/
checkpoint
07.12.2025 16:31Ох сейчас Вас запинают за такое... но я Вас поддержу. Makefile и vi - наше всё! :)

Whitech
07.12.2025 16:31Извините, но сразу видно, что для Вас это исключительно хобби и Вы никогда не писали чего-то серьезного, где необходимо обеспечивать функциональную безопасность (ISO 26262, IEC 61508, IEC 62304, DO-178C и др.) и сертифицироваться. Ладно, статический анализатор на MISRA/CERT/CWE можно прикрутить внешний. Но Вы ярко отгребете на этапе доказательства пригодности инструмента (Tool Qualification) с gcc, а потом еще что делать с LTS не будете знать. Называть сертифицированные промышленные инструменты "IDE для школоты" это, извините, показывает Ваш уровень далеко не в лучшем ключе.

aabzel Автор
07.12.2025 16:31Проблема IDE-IAR-в том, что все конфиги хранятся в xml подобном ewb файле.
В результате при создании отдельной похожей сборки происходит 100% дублирование конфигов (макросы препроцессора, пути к заголовочным файлам и индексация исходников). Всё копируется.
Это существенно препятствует масштабированию кодовой базы.
Для прототипирования единичных поделок IAR-идеальное решение.
Для DevOps IAR - беда и проблема.IAR не позволяет наследовать конфиги. Понимаете?

aabzel Автор
07.12.2025 16:31У меня был случай, когда была одна Legacy IAR-IDE сборка 55-ю конфигурациями для разных клиентов.
Надо было для всех конфигураций написать ещё пару *.c файлов. Дак вот...
Код я написал за 3-4 часа. Однако у меня ушло две недели тупо на то, чтобы просто в каждую конфигурацию мышкой в IDE-IAR добавить папку, прописать пути к этой папке и добавить макросы в GUI IDE.
Вот так, господа…
В GNU Make это же делается одной строкой.Вот и делайте выводы..

aabzel Автор
07.12.2025 16:31Сейчас писк моды - делать отладку через WEB интерфейс
Вот именно, что моды.
Мода приходит и уходит. Классика - остается.

karenic
07.12.2025 16:31Но реально на сегодня лучшие инструменты отладки имеют коммерческие тулсы типа IAR или Keil. Поэтому многие SDK от производителей чипов имеют варианты для IAR.
Любовь к IDE IAR/Keil - это типичный признак молодых начинающих программистов микроконтроллеров.
Те кто в теме собирают прошивки самостоятельно написанными CMake скриптами.

EmCreatore
07.12.2025 16:31CMake на ура теперь конвертируются в IAR XML с помощью Claude.
Вообще никакой проблемы. И линкерные файлы с тем же успехом конвертирует.
Сейчас про скрипты писать - высасывать тему из пальца.
Я за час превел весь хостовый стек с CMake Espresiff на IAR.
И еще кучу хлама от туда выкинул.
Дебажу теперь его c C-Spy в хвост и в гриву. Юзаю всю мощ таймлайнов, ITM ивентов, live view , RTT monitor, tracing. Потому что Espresiff со своим GNU создал неимоверный шлак.
CLI - просто жалкий лепет зеленого джуниора, которого только что от ардуины оторвали.

aabzel Автор
07.12.2025 16:31CMake на ура теперь конвертируются в IAR XML с помощью Claude.
Обожаю, когда меня называют джуном. Чувствую себя снова молодым.
Почему бы Вам не написать на Habr заметку про это?
Название может быть таким:
"Сборка компилятором IAR через скрипты CMake".
EmCreatore
07.12.2025 16:31Возраст здесь ни при чём.
Я видел пенсионеров, которые ради фана подсаживаются на архаичные практики — и это нормально.
Но не надо выдавать это за ноу-хау, чтобы получить признание.Я вам так скажу.
Если вы работаете с 8–16-ногими микроконтроллерами, используйте чипы с no-code-фреймворком вроде MSP Zero Code Studio и оставьте свои скрипты в прошлом.
Если чипы более мощные, то RTT, SWD, USB — обязательно. И чтобы ОЗУ хватало для развёртывания веб-сервера. Тогда вы получите и скорость, и мощность отладки.Чем быстрее отладочный вывод получает Claude, тем больше итераций в час он успевает сделать.

checkpoint
07.12.2025 16:31Боюсь, что Ваша ортодоксальная каноническая прошивка в наш православный MIK32 не влезет. Приходится ограничиваться минимумом: WTD, SysTick, UART и Heart Beat. :-)
PS: Вы забыли про режимы "сна".

aabzel Автор
07.12.2025 16:31Боюсь, что Ваша ортодоксальная каноническая прошивка в наш православный MIK32 не влезет.
Очень даже влезет.
Вот сборка
https://github.com/aabzel/trunk/tree/main/source/projects/start_mik32_v1_generic_gcc_mNVRAM на EEPROMе сделал.
https://habr.com/ru/articles/815639/
Просто код исполнять надо из SPI-FI.

checkpoint
07.12.2025 16:31Просто код исполнять надо из SPI-FI.
Ну это совсем не спортивно. :)
Кстати, как Вы сообщаете компилятору чтобы он перенес строки текста в SPIFI ? Ничего лучше чем
attribute((used, section (".spifi.text")))перед обьвлением переменной я пока не придумал.
aabzel Автор
07.12.2025 16:31Там надо сделать только одно изменение в ld файле для компоновщика.
И прошивка специально соберется для SPIFI.
Не нужны аттрибуты.
checkpoint
07.12.2025 16:31Поясню. В наших проектах используется оба вида памяти - EEPROM и SPIFI. По умлолчанию компилятор запихивает все строки в сегмент .rodata, который размещается в EEPROM (нам важно чтобы .rodata был именно в EEPROM). Как сказать компилятору, чтобы все строки уходили в сегмент .spifi.text или в .spifi.rodata которые размещаются в SPIFI ?

devprodest
07.12.2025 16:31В скриптах линкера поменяйте и всё

checkpoint
07.12.2025 16:31Что именно поменять? Есть пример ? В скриптах можно отправить весь .rodata в SPIFI, но этого как раз мне не надо. Мне требуется отправить в SPIFI только строки.

aabzel Автор
07.12.2025 16:31Боюсь, что Ваша ортодоксальная каноническая прошивка в наш православный MIK32 не влезет.
Вот пожалуйста,
Исчерпывающая инструкция про то, как запустить ОКФП на нашем MIK32
https://habr.com/ru/articles/854050/
Настройка ToolChain-а Cборки Прошивок для MIK32 (K1948BK018 + C + GCC + GNU Make + OpenOCD)++Сорцы
https://github.com/aabzel/trunk/tree/main/source/projects/start_mik32_v1_generic_gcc_m

grand1987
07.12.2025 16:31Более-менее согласен с содержанием, но по форме (т.е., архитектуре) есть вопросы :).
2--Сборка без RTOS.
Согласен для прошивок < 100KB. Для сложных приложений на > 1MB сложно поддерживать приложение на самописном планировщике, в том числе переносимость на экзотичные MCU.
3--В сборке присутствуют драйверы для следующих базовых фундаментальных аппаратных подсистем: Clock, MCO, PLL, NVIC, SysTick, GPIO, PINMUX, FLASH, TIMER, DMA, UART.
Здесь я бы разделил драйвера или точнее добавил бы пункт в "джентельменский набор": 3.1 стартап (инициализация PLL, Clock, MPU, RAM/Flash, переменные bss/data и т.д.) и 3.2 драйвера для приложения. Также, налиние Flash драйвера в приложении приведет к вопросам от аудиторов проекта.
4--В сборке присутствует HeartBeat LED.
Это можно сделать и через переодический опрос устройства по интерфейсу связи, тот же UART. То что LED мигает не означает что устройство полностью функционально.
11--Также следует сразу подготовить отдельную сборку загрузчика через UART-CLI.
У вас загрузчик и приложение в одной прошивке? (в моей интерпретации, прошивка это софт собранный как отдельный/самостоятельный исполняемый файл)

aabzel Автор
07.12.2025 16:31У вас загрузчик и приложение в одной прошивке?
Нет. Это две отдельные сборки.
Как бинари они прописаны в flash памяти. Загрузчик в начале Flash, приложение в конце Flash памяти. Между ними NVRAM (FlashFS).
tigreavecdesailes
Нелогично, вы выкинули RTOS, но добавили самодельный планировщик и несколько других пунктов, которые по своей сути представляются отдельными потоками.
Если не ориентировать эту базу на что-то типа 8/16/32 атмег, то, наверное, можно спокойно везде использовать FreeRTOS как основу.
aabzel Автор
С RTOS тянется слишком большой overhead.
Да и потом. Чтобы запустить RTOS вам как ни крути нужны CLK, PLL, TIMER, SYSTICK, NVIC и т п.
tigreavecdesailes
Зато, в свою очередь, задачи типа Heartbeat LED и другие не realtime задачи не требуют отдельных таймеров и прерываний, а работают как потоки RTOS просто в цикле засыпая на нужное время или ожидая сообщения в очереди.
aabzel Автор
Лишние сложности с реентабельность кода, deadLock-ами, гонками, клинчами.
Загрузчику RTOS с доплатой не нужна.
В generic приложении - пожалуйста.
devprodest
Зато загрузчик с лишним CLI и запуском тестов очень необходим. Где-то вы перегибаете.
Какие сложности в реентерабельности?
aabzel Автор
Загрузчику тесты не нужны. А CLI нужна для загрузки прошивки.
aabzel Автор
Я имел в виду кооперативный планировщик. Не вытесняющий.
aabzel Автор
Нельзя. Так как прошивку порой надо еще симулировать как процесс на PC.
Чтобы тестировать математику.
Как вы запустите FreeRTOS в консольном приложении?
tigreavecdesailes
Я это не пробовал, и воообще мой опыт сугубо хоббийный, но для FreeRTOS заявлена работа на x86 в real mode, то есть можно запускать в виртуалке. И ещё написано что порт под линукс есть.
aabzel Автор
Вот попробуйте.
Это сложно делается.