Часто слышал мнение, что в embedded программировании в принципе не может быть никакого DevOps(а).  Якобы вот есть GUI(ня) в IAR и там надо много мышкой водить. "Ты же не станешь ставить шаговые двигатели для сдвигания мышки" и т. п. В этом тексте я намерен пофантазировать каким мог бы быть абстрактный процесс разработки firmware с точки зрения DevOps. И перечислить атрибуты такого процесса. Это может быть. Git, SVN, Mercurial, ClearCase, Perforce. Репозиторий нужен не только для хранения, распространения кодовой базы среди разработчиков, но и в случае поломки сборок репозиторий позволит откатиться в истории на прежние версии кода, когда все было относительно хорошо. Можно восстановить случайно удаленные файлы. Репозиторий позволяет распределить работу среди нескольких вкладчиков. Контроль версий запоминает все шаги. С репозиторием намного спокойнее работать.   Плохие примеры когда код в компании передают через DropBox, USB-Flash(ку) или архивом в электронном письме. В этом случае нет никаких гарантий, что у каждого разработчика та же версия, что у остальных. 2. Код-генерация В firmware проектах часто много повторяющегося кода. Это синтаксический разбор содержимого payload бинарных пакетов (например CAN, RS485 и пр.). Синтаксический разбор регистров каких-н умных навороченных периферийных SPI, I2C, MDIO микросхем (драйверы сенсорных экранов, внешние ADC, трансиверы, драйверы исполнительных механизмов, интеллектуальное управление питанием и пр.).   Для автоматизации написания кода синтаксического разбора можно прибегнуть к созданию простых консольных утилит код-генераторов. На основе текстовых файликов структуры пакета при помощи код генераторов можно мгновенно сформировать огромные *.c *.h файлы. Код генератор повысит гибкость проекта, уменьшит вероятность ошибки, ускорит внесение изменений.  Многие IDE (IAR, Code Composer Studio) могут запускать сборки из командной строки Windows, просто запустив *.bat скрипт. Запускать сборки со скриптов полезно еще и по той причине, что окна GUI(ни) в IDE IAR часто зависают.  А в окно log(а) сборки в CCS не помещается весь текст 6 минут работы компилятора и теряются первые сообщения о критических предупреждениях. Если вы собираете проект из скриптов, то у вас останется log файл компилятора и вы сможете проанализировать все сообщения и исправить их.  Чтобы создать хорошую модульную кодовую базу с полной изоляцией компонентов надо собирать проект по частям. Подобно тому как в математике интегрируют по частям. Например если это IoT устройство, то надо подготовить сборку только с GNSS, сборку только с LTE модемом, сборку для проверки качества пайки платы, загрузчик, приложение, сборка с тестами. Также полезно сделать сборку для какого-н другого микроконтроллера (ESP32, STM, TI, AVR). Это даст гарантию, что код переносимый. Если каждая сборка собирается без ошибок, то это значит, что код достаточно модульный. Когда Make файлы являются для вас исходниками, то вы можете делать супер модульный код. Буквально одной строчкой в *.mk  файле добавлять и исключать компоненты из сборок. Если же вы привыкли пользоваться IDE, то вам для добавления одного компонента придется в одной вкладке IDE добавить пути к include(ам) в другом окне добывать переменные препроцессора, в третьем окне IDE добавлять сами *.с файлики и так для всех 55 сборок. И это все мышковозня. В Make файлах это будет 1 строка.  IDE хороши в основном для прототипирования. Разработчики, которые пользуются только IDE не понимают какой путь проходит код от написания до попадания в Flash. Не догадываются даже о существовании файлов с расширениями *.mk,*.a, *.opt, *.so, *.dot, *.i, *.asm, *.o, *.icf, *.ld,  *.cmd, *.elf, *.out, и прочее. Хотя все эти файлы мелькают в workspace директории. В промышленном подходе к разработке надо писать Make *.mk файлы вручную и подвергать их версионному контролю.https://habr.com/ru/articles/723054/ После компиляции код следует подвергать статическому анализу. Можно воспользоваться бесплатным CppCheck. Это позволит выявить и исправить еще некоторые критические ошибки.  Можно клонировать код из репозитория и выяснить, что он уже как полгода не собирается и никто об этом не догадывался так как код собирался только локально на DeskTop(е) разработчика. Забыли подвергнуть версионному контролю какие-то файлики. Кодовая база в репозитории должна быть валидной каждый день. То есть сборки должны собираться без ошибок и без предупреждений компилятора из кода, что в репозитории. Кто за этим будет следить? Когда есть репозиторий и скрипты сборки можно автоматизировать запуск сборок при помощи бесплатной программы Jenkins. Это утилита с Web интерфейсом, которая запускает скрипты. Когда работает Jenkins, то можно не только удостовериться, что код синтаксически правильный, но и всегда каждый день брать свежие артефакты. Там есть удобная навигация и сортировка по категориям Job(ов). Можно даже открыть доступ Jenkins(у) клиентам продукта и они не будут беспокоить разработчиков вопросами, где же нам взять прошивку. Клиенты сами смогут взять ту прошивку, которая им нужна из Jenkins. Настроить Jenkins это весьма кропотливая работа и много мышковозни. Запускать CI на каждом компьютере каждого разработчика это еще и бессмысленная повторная работа. Плюс нагрузка LapTop(а), лишний шум во время работы от кулера. Но это достаточно сделать 1 раз для всех разработчиков. Нужен какой-то общий компьютер. Можно задействовать дешевенький Win(довый) NetTop PC (Зомбик). Запустить на нем Jenkins и оставить работать 24/7. За ночь он соберет все сборки. Когда кому-то понадобился артефакт, то он подключается по Win Remote Desktop Connection или TeamViewer к зомбику и скачивает себе артефакт, посмотрит все ли в порядке с остальными сборками и в случае поломки сделает коммиты, чтобы починить код. https://habr.com/ru/articles/695978/ То что код собирается в репе это еще ни о чем не говорит. Код может собираться без единого предупреждения, а при загрузке на target плата будет бесконечно Reset(тся). Код должен корректно стартовать и исполняться. Как это проверить автоматически? Это можно сделать при помощи модульных тестов. Модульные тесты это просто функции, которые запускают другие функции и проверяют output. Должна быть сборка для тестирования программы изнутри (методом белого ящика). В идеале надо тестировать все нетривиальные функции. В каждом firmware проекте есть hardware зависимый  код и hardware независимый код (математика, строки, абстрактные структуры данных). Часть кода, который не зависит от железа можно собирать, запускать и тестировать прямо на x86-64. Памяти на PC много  и все тесты поместятся. В Jenkins должен быть отдельный Job для запуска тестов на PC.  Если же в MCU не хватает достаточно NorFlash памяти для сборки проекта с модульными тестами, то можно задействовать отладочную плату с чипом того же семейства но с большим объёмом  NorFlash. Подключив нужную периферию перемычками получится прототип тестируемого устройства. https://habr.com/ru/articles/698092/ Остаются аппаратно-зависимые тесты. Их надо запускать и выполнять прямо на target(е). Чтобы это автоматизировать надо минимум 3 вещи. Устройство, загрузчик и CLI. Соединив Target c NetTop компьютером по UART получится HIL стенд. Загрузчик позволит автоматически обновлять прошивку по тому же UART. CLI позволит подключиться к target по UART и запустить тесты, вычитать лог и сохранить отчет. Все это можно упаковать в отдельные Job(ы) на Jenkins.  Как понять, что составлено достаточно модульных тестов? Может случится, что какие-то строки протестированы 100 раз а другие ни разу. Ответить на этот вопрос можно только если как-то считать по каким строкам код прошил во время тестов, а какой код является недостижимым. Для этого есть специальные проприетарные Tool(ы) например Testwell CTC++.   Ежедневные планерки Когда несколько разработчиков делают одну кодовую базу надо как-то координировать действия, переоценивать трудоемкость задач, расставлять приоритеты, сообщать от том что сделано, какие есть загвоздки и что каждый собирается делать. Для этого надо собираться каждый день в первой половина на 5...7 минут и устно проговаривать. Так можно исключить ситуации, когда одно и то же сделано несколько раз каждым разработчиком. Еще раз хочу отметить, что все перечисленные 12 DevOps атрибутов всего на всего плоды моей фантазии. И если кто-то увидит в этом какие-то корреляции с реальностью, то это всего лишь совпадение.   При налаженном DevOps можно организовать полностью удаленную работу даже для процесса разработки Firmware. Разработчику достаточно делать коммиты в репозиторий и анализировать Job(ы) Jenkins(а) и изредка подключаться к HIL стенду. В теории не обязательно даже локально устанавливать ToolChain, ничего кроме своего любимого текстового редактора и браузера. Так 1 человек может контролировать до 20 сборок. Надеюсь этот текст поможет кому-нибудь автоматизировать свои проекты. Если есть дополнения, то предлагаю обсудить их в комментариях. Links: CI/CD прошивок для микроконтроллеров в Wiren Board (Начало на 25:50) https://www.youtube.com/watch?v=HEEVxZ4rBCo&t=366s Конвеерум #30: Эволюция рабочего окружения для embedded разработки https://www.youtube.com/watch?v=vmuO4bHjTSo&list=WL&index=1 https://www.youtube.com/watch?v=vmuO4bHjTSo&t=12s 17 атрибутов хорошей PCB https://habr.com/ru/post/655879/ 9 атрибутов хорошего firmwarehttps://habr.com/ru/post/655641/  Embedded SW/Firmware Engineer