В программировании микроконтроллеров помимо написания прошивок ещё периодически приходится писать клиентские программы для загрузки *.hex файлов в микроконтроллер через загрузчик.

Как водится, самое сложное в этом процессе - это сесть и написать ТЗ. Только после ТЗ появляется ответ на извечный вопрос: "что делать?".

В самом классическом случае loader - это консольное windows приложение. Такие утилиты зачастую поставляют сами производители микроконтроллеров: STm, TI, Nordic Semiconductor и пр. Так как boot пины позволяют производить загрузку прошивки из UART. Еще такие загрузчики пишут сами продуктовые компании для DevOps процессов внутри компании и для пользователей того или иного прибора.

В этом тексте я попробовал порассуждать на тему того, какой же должная быть эта самая утилита FW_Loader.

Определения

Алгоритм — последовательность действий.

Программа — алгоритм написанный на языке программирования.

Процесс — исполняемый экземпляр программы в памяти.

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

Прошивка (firmware) — содержимое энергонезависимой памяти электронного устройства с микроконтроллером. В прошивке всегда есть код, а иногда ещё образ файловой системы NVRAM, конфиги процессора. Монолитная прошивка может содержать ещё и загрузчик.

Загрузчик — это отдельная прошивка, которая загружает другую прошивку. Обычно загрузчик стартует сразу после подачи питания перед запуском приложения. Это чисто системная часть кода.

CLI — Интерфейс командной строки. Это способ взаимодействовать с программой обменом текстами по принципу запрос‑ответ.

connectivity — всё что связано с интерфейсами и протоколами.

Обязательные технические требования

Общий план таков, что надо загрузить прошивку в память при помощи тандема on-chip загрузчика и утилиты FW_Loader по UART. То есть обновить прошивку без программатора. Условно FW Loader - это консольное Windows PC приложение для нарезания .hex (или bin) файла и отправки фрагментов прошивки по последовательному COM порту.

1--Утилита FW_Loader должна быть консольным приложением. Консольное приложение проше протестировать и быстрее написать. Также консольным приложением можно управлять из других программ.

2--Программа FW_Loader должна быть собрана для OS Windows. Это самая распространенная ОС.

3--Программа FW_Loader должна обладать своей собственной системой команд. Система команд это ключи, аргументы командной строки.

4--Все команды должны вызываться, как в интерактивном режиме, так и в пакетном режиме.

5--Аргументы командной строки должны быть позиционными. Самый главные аргументы в начале. Вспомогательные аргументы в конце. Это наиболее простой и быстрый способ для реализации в коде.

6--Программа FW_Loader должна быть собрана на языке программирования Си.
Это позволит пере использовать исходный код между прошивкой и PC программой для FW_Loader. Дело в том, что утилиту Loader, как привило пишет тот же программист, что и программирует сам микроконтроллер. А так, как сам загрузчик написан на Си, поэтому есть резон и приложение писать тоже на Си.

7--Утилита FW_Loader должна уметь проверять нынешнее содержимое прошивки в ROM памяти с указанным *.hex файлом. Так называемый режим верификации содержимого памяти.

8--В утилите FW_Loader должна быть команда ping для проверки физического соединения между PC и электронной платой.

9--У утилиты FW Loader должен быть интерактивный режим. То есть режим командной строки в stdio. Подобно тому, как это происходит в программе BusyBox.

10--У утилиты FW Loader должен быть пакетный режим. То есть утилита должна отрабатывать свои аргументы командной строки и сразу после этого завершать свое исполнение.

11--Программа FW_Loader должна работать с *.hex файлом.

12--Программа FW_Loader должна работать с *.bin файлом. В этом случае надо отдельно указывать по какому смещению следует прописывать данный bin файл.

13--Утилита должна записывать прошивку по частям. Микроконтроллер всё равно не сможет разместить всю прошивку в RAM памяти.

14--Программа FW_Loader должна позволять конфигурировать паузу между отправкой байтов в COM порт аргументами командной строки. Это нужно, чтобы загрузчик не захлебнулся от интенсивного потока входных байт. Также полезно при отладке.

15--Пауза между отправкой байтов должна передаваться через командную строку, как аргумент команды.

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

17--Программа FW_Loader должна возвращать код ошибки в случае неудачного подключения и прошивки.

18--Программа FW_Loader должна собираться из скрипта сборки . Это позволит подключить её к серверу сборки Jenkins.

19--Программа FW_Loader должна быть одно-поточным процессом в операционной системе.

20--Программа FW_Loader должна собираться из скриптов сборки GNU Make.

21--Программа FW_Loader должна содержать модульные тесты.

22--Битовая скорость UART должна передаваться через ключи утилиты.

23--После обновления утилита должна давать команду прыжка в приложение.

24--У каждой CLI команды утилиты FW_Loader должна быть справка. Справку можно изучить в интеррактивном режиме работы утилиты буквально набрав название команды.

25--Должна быть предусмотрена возможность вычитывать содержимое физической памяти из MCU.

26--По окончании обновления утилита FW_Loader должна печатать отчёт об обновлении прошивки: продолжительность обновления прошивки в секундах, размер бинаря, битовая скорость обновления. Эти метрики и будут являться критериями эффективности процесса обновления прошивки.

27--Программа FW_Loader должна поддерживать по меньшей мере два протокола передачи данных. Бинарный протокол для крохотных загрузчиков размером 8kByte....32kByte ROM. И текстовый CLI-образный протокол для больших полноценных загрузчиков.

Желательные технические требования

1--Желательно, чтобы программа FW_Loader была так же собрана для OS Linux. В современных реалиях Linuх более приоритетная ОС для утилит.

2--Желательно сделать аргументы командной строки именованными (то есть с ключом префиксом), а не позиционными. Это позволит передавать аргументы в любой последовательности.

3--Желательно, чтобы фрагменты прошивки передавались в зашифрованном виде. Шифрование особенно нужно только если обновление по сети происходит, и есть вероятность перехвата трафика.

4--Желательно, чтобы фрагменты прошивки передавались в сжатом виде. Хотя бы в кодировке BASE64. Это позволит сократить продолжительность обновления.

5--Желательно, чтобы FW_Loader могла проверять нынешнюю версию загруженной прошивки. Дело в том, что в автоматических DevOps процессах нет смысла обновлять новую версию прошивки на старую версию. Утилита должна хотя бы выдавать предупреждение, что возникла такая ситуация.

6--UART-bootloader имеет смысл делать реализацию стандартных протоколов типа xModem, тогда и утилиты не потребуется.

Механизм обновления

В самом классическом виде обновление прошивки происходит через последовательный виртуальный COM порт благодаря микросхемам-переходникам с USB на UART (CP2102) на максимально возможной битовой скорости 921600 бит/c. Параметры кадра: два стоповых бита, нет проверки четности, один кадр - 8 бит.

Перед обновлением необходимо проверить link, проверить нынешнюю версию прошивки, отправить пакет стирания содержимого микросхемы. Далее записывать области памяти и проверять, что фактически данные тоже прописались.

В конце отправить микроконтроллеру команду прыгнуть по начальному адресу и исполнять прописанное приложение.

Итог

Вот такие базовые атрибуты для утилиты Loader мне удалось выделить. Разумеется тема обновления прошивки намного шире. Загрузчик это не только ещё одна прошивка в репозитории. Для загрузчика нужна полноценная инфраструктура и экосистема. В самом простом виде это консольное Win приложение (FW Loader) под PC для отправки прошивки по serial COM порту. А для искушенного пользователя надо ещё сделать FW Loader c GUI-интерфейсом, потом загрузку из браузера Chrome/Opera/FireFox. Причем надо всё сделать под три-четыре операционки: Windows, Linux, Mac. Также нужно мобильное приложение для отправки прошивки из-под Android и iOS. И ещё нужен Web-сервер с авторизацией для поиска на земном шарике всех не обновлённых электронных зубных щеток и раскатывания новых обновлений FW на смартфоны их владельцев. Поэтому загрузчики и Loader-ы это на самом деле очень-очень много работы.

Если есть, что добавить, то пишите в комментариях.

Словарь

Акроним

Расшифровка

FW

FirmWare

OS

Operation System

ТЗ

Техническое задание

DFU

device firmware update

UART

universal asynchronous receiver-transmitter

CRC

Cyclic redundancy check

Ссылки

#

Ссылка

URL

1

Intel HEX: описание формата файла

https://microsin.net/programming/pc/intel-hex-file-format.html

2

Как собрать Си программу в OS Windows

https://habr.com/ru/articles/754972/

3

Атрибуты Хорошего Канального Протокола Передачи Данных

https://habr.com/ru/articles/682292/

4

Атрибуты Хорошего Загрузчика

https://habr.com/ru/articles/754216/

5

Работа с последовательным портом в windows и linux

https://habr.com/ru/sandbox/30635/

6

COM-порт в Windows (программирование)

https://ru.wikibooks.org/wiki/COM-порт_в_Windows_(программирование)

7

OpenBLT

https://www.feaser.com/openblt/doku.php

Комментарии (3)


  1. 4chemist
    13.05.2025 20:24

    Тут идут слова благодарности конторе Espressif с ее серией микроконтроллеров с Wi-Fi. Никогда еще не было так легко обновить прошивку по воздуху. Никаких проводов, разъемов, гальванических развязок, USB-to-serial переходников, настроек скорости последовательного порта, командировок. Даже софта FW_loader не надо! В вебморде выбрал прошивку с рабочего стола ноутбука, из теплого офиса с удобным креслом за тысячу километров от железки, и, с чувством достоинства, нажал кнопку "Загрузить". Поработал и получил денег кучу.


  1. VO_Obsidian
    13.05.2025 20:24

    Не совсем понятно для кого эти требования подходят. В большинстве случаев удобнее всего сделать обёртку над фирменными утилитами, например STM32CubeProgrammerCLI или esptool. Ну и тут уже половина требований можно считать выполненными, т.к. они реализованы в них.


  1. grand1987
    13.05.2025 20:24

    6--Программа FW_Loader должна быть собрана на языке программирования Си.

    Питон + pyinstaller / bincopy / serial и argparse решают задачу. Если надо добавь шифрование, также решается добавлением библиотеки. Также питон однопоточный.