" Все интерфейсы и протоколы только и нужны, чтобы сделать memcpy() "

В программировании микроконтроллеров помимо написания прошивок ещё периодически приходится писать клиентские программы для загрузки *.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 порту.

0--В утилите FW_Loader должен быть progress bar. Индикатор прогресса. Чтобы оператор мог непрерывно оценивать сколько ему еще ждать окончания обновления прошивки. Нет ничего мучительнее, чем неизвестность.

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

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

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

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

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

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

29--Программа FW_Loader должна автоматически определять COM порт на котором находится наш target процессор. Программа FW_Loader должна уметь сканировать все доступные в операционной системе COM порты и находить тот COM port на котором подключена электронная плата.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

27--В случае с ARM Cortex-M процессорами Loader должен проверять массив векторов прерываний и указатель на верхушку стека. Если там валидные значения, то позволять записывать. Если не валидные то блокировать запить. Всё равно такая прошивка зависнет.
К сожалению в RISC-V всё по-другому и там, глядя на бинарь, не к чему прицепиться.

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

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

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

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

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

4--В CLI режиме желательно, чтобы фрагменты прошивки передавались в сжатом виде. Хотя бы в кодировке BASE64. Это позволит сократить продолжительность процесса обновления прошивки на 15%..25%. Посмотрите сами. Записи на BASE64 занимают меньше или равно символов. Я имею в виду, что hex - текстовый. То есть BASE16. Один байт кодируется двумя символами. 4 бита кодируются одним символом. В BASE64 же 6 битов кодируются одним символом. Вот и получается сжатие на 33%.

BASE64 len

BASE64

hex=BASE16

hex len

8

AAAAAAA=

0000000000

10

8

/////w==

FFFFFFFF

8

12

DJ4MdKaHIe4=

0c9e0c74a68721ee

16

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

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

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

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

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

Кода вообще не нужен Loader?

Вы удивитесь, но на самом деле утилита даже Loader не нужна, если

1--к микроконтроллеру подключена SD карта. В этом случае Вы можете монтировать SD карту к LapTop, скопировать *.hex. Затем запустить в прошивке SPI, FatFs, читать прошивку и записать ее в on-chip Flash прямо загрузчиком. Именно так и происходит обновление прошивки на портативных диктофонах.

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

Итог

Вот такие базовые атрибуты для утилиты 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

8

hex-to-base64

https://cryptii.com/pipes/hex-to-base64

Only registered users can participate in poll. Log in, please.
Вы писали DeskTop утилиты для взаимодействия с микроконтроллерными загрузчиками?
45.45%да10
54.55%нет12
22 users voted. 1 user abstained.