При проектировании устройства на микроконтроллере бывает встает вопрос об обновлении прошивки прибора. Причем сам процесс обновления прошивки должен быть простым и доступным для обыкновенного пользователя. И конкретно для микроконтроллера STM32F103C8 возможна загрузка прошивки по UART. То есть к схеме необходимо добавлять микросхему конвертера USB-UART. Либо воспользоваться аппаратными возможностями USB микроконтроллера, что я и сделал. Меня заинтересовал вопрос о возможности обновления прошивки по USB. На некоторых МК даже есть аппаратный USB-загрузчик, но только не на STM32F103C8, поэтому пришлось все программно реализовывать. По программной части для STM32 существует USB Library от STMicroelectronics с реализованными классами USB и примерами. В частности заинтересовал класс DFU т.е. загрузка прошивки по USB. В данном классе уже реализован свой набор команд для взаимодействия МК и приложения на ПК "STM32CubeProgrammer". Но мне хотелось что-то своё, кастомное и неограниченное данным набором команд. И пришла мысль "А почему бы не реализовать всё это в классе CDC?". Тут и размер загрузчика примерно таким же оказался, но главное можно реализовать свой набор команд, работать на ПК с последовательным портом и соответственно понятнее, как написать приложение для ПК. У меня есть небольшой опыт написания приложений с использованием библиотеки QT на С++, поэтому с ее помощью была создана программа для USB загрузчика.
Рассмотрим работу и настройку самого загрузчика на МК. Проект создан в STM32CubeIDE, размер загрузчика получился 15 кБ. В файле main.c есть условие при котором МК работает в режиме загрузчика, либо управление передается пользовательскому приложению:
if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==GPIO_PIN_RESET));
Мы можем по желанию задать любое условие входа в режим загрузчика, в моем случае нужно замкнуть ножку В0 на землю при загрузке МК. И тогда МК перейдет в режим загрузчика и при подключении по USB на стороне ПК будет определяться как виртуальный COM порт. В ином случае будет выполняться основная прошивка. В файле Memory.h заданы адреса начала основной прошивки и конца памяти программ:
#define APPLICATION_ADDRESS 0x08003C00
#define FLASH_END 0x0801FFFF
Теперь подготовим пользовательскую прошивку к загрузке. Для примера возьмем простое моргание светодиодом. В проекте для CubeIDE в файле STM32F103C8TX_FLASH.ld нужно изменить адрес начала выполнения программы на 0х8003С00:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8003C00, LENGTH = 64K
}
В файле system_stm32f1xx.c задать смещение таблицы векторов 0х3С00:
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x3C00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200.
*/
Теперь можно перейти к загрузке данной прошивки. Ставим перемычку на ножке B0 и подключаем по USB плату. Запускаем приложение "USB CDC Программатор":
Для поиска доступных COM портов нажимаем "Обновить", в списке выбираем появившийся порт и нажимаем "Подключить". Выдаст сообщение об успешном подключении платы и название кнопки подключения изменится на "Отключить":
Если до этого в плату была загружена другая прошивка, то ее необходимо удалить, нажав на "Стереть". При этом затирается вся область памяти начиная с адреса 0х8003С00 и до конца памяти программ. Далее нажимаем "Открыть" и в диалоговом окне выбираем файл прошивки в формате .bin (Пока поддерживается только такой формат файлов). В таблице появляются данные прошивки, в логах название и размер файла. Нажимаем "Загрузить" и через некоторое время прошивка будет загружена:
Теперь можно отключить плату, убрать перемычку и убедиться в работоспособности прошивки. При необходимости возможно считать прошивку и сохранить ее в файле на компьютере. Считывание памяти МК происходит начиная с адреса 0х8003С00 и до первого числа 0хFFFFFFFF.
К статье прикладываю:
Комментарии (29)
mikelavr
12.10.2021 08:03+4У обновления прошивки через USB CDC есть недостаток - в ОС надо ставить драйвер. Если изделие обновляется не специалистом - это может быть проблемой. Например пользователь может не иметь в системе прав администратора. Кроме того, в программе обновления надо выбирать конкретный UART порт из имеющихся в системе (или организовать сканирование с автоопределением).
Решение: USB HID. Драйвер ставить не нужно, он уже есть в ОС. Недостаток - достаточно медленная передача данных из за особенностей реализации в ОС.
Arcanum7
12.10.2021 10:20Ну и загрузчик USB HID занимает много места. На F103 это критично.
COKPOWEHEU
12.10.2021 19:16Ну и загрузчик USB HID занимает много места.
Не знаю сколько занимает запись во флеш контроллера, но вряд ли больше половины от HID. Ну пусть даже столько же, суммарно что-то около 5 кБ. Из 64 кБ, доступных в f103c8t6. Менее 8%.
С HID в другом проблема: ему нужна программа-прошивальщик. Так просто (для пользователя) как с MSD или CDC уже не выйдет.
IronHead
12.10.2021 12:23+3Идеальный вариант — web usb.
Драйвера не нужны
В хроме и ему подобном работает из коробки
Обновить прошивку можно прямо с сайта
Попробовать можно здесь
https://devanlai.github.io/webdfu/dfu-util/Xadok
15.10.2021 11:27идеальным такой вариант не может быть (как раз из-за хрома и веба)
IronHead
15.10.2021 11:45<sаrcasm> ну да, зачем облегчать жизнь конечному пользователю
Он мог просто зайти на сайт и нажат кнопку обновить прошивку.
Но пользователь должен страдать, нужно заставить его ставить драйвера, перезагружаться чтобы включить поддержку драйверов без цифровой подписи и пр.
</sаrcasm>Xadok
15.10.2021 11:47Поэтому мы сделали обновление прошивки через hid, когда драйвера не нужно ставить и перезагружаться тоже не нужно.
IronHead
15.10.2021 12:17Я тоже делал обновление прошивки через HID
Для того, чтобы обновить прошивку через HID нужно:
1) Зайти на сайт
2) Скачать и сохранить у себя файл прошивки
3) Скачать себе софтину для обновления прошивки
4) Выбрать в софтине для прошивки нужный файл прошивки и прошитьИ как показала практика — 90% пользователей совершают ошибки в п2-4.
Поэтому для себя решил — что лучше не напрягать пользователя лишними этапами.
Все таки обновление прошивки нужно не пользователю, а вам, производителю.
Пользователь хочет получить просто работающий девайс, ну может быть какие то дополнительные плюшки, если девайс можно безболезненно прошить, ничего для этого не устанавливая на свой ПК и не скачивая никаких файлов.Xadok
15.10.2021 12:37Да, обновление прошивки конечный пользователь у нас не совершает. Но бывает, что прошивку нужно обновить и с хрюши, и с ноута с семеркой. Мы можем гарантировать, что наше ПО работает на всём. Но не можем гарантировать, что там будет хотя бы хром и уж тем более, что он работать будет.
За скобками оставляем тот факт, что браузер как бы и не должен иметь доступа к железу.
screep123
13.10.2021 08:20+3Не затронуты вопросы:
Проверка целостности образа прошивки;
Проверка версионности прошивки (обновление только в том случае, если версия образа >= версии в памяти МК);
Шифрование прошивки;
Что будет если новая прошивка начала заливаться и не закончила? Новая прошивка должна заливаться в резервную область (внешнюю память), там распаковываться, проверяться и если все норм уже копироваться в рабочую память
КМК без всего этого вопрос как заливать образ второстепенен... Даже если мы работаем по удобному MSD все равно найдется пользователь который скопирует туда что-то не то и получит кирпич.
STMshchik Автор
13.10.2021 08:24Хорошие замечания. По сути в память МК сейчас возможно зашить любой мусор. Есть над чем работать. Тут действительно нужно довести до ума и подправить статью
Xadok
15.10.2021 11:31Товарищ верно подметил, если учесть все эти моменты, то процесс прошивки становится намного более сложным.
У нас сначала прошивка заливается, проверяется, а потом отдельной командой переставляем указатель и перезапускаемся.
Andy_Big
15.10.2021 21:22Вот п.2 во многих случаях - зло. Скачал новую прошивку, залил ее, а в ней глюк. И уже не вернешься на старую, потому что "проверка версионности" :)
ivan_kononoff
14.10.2021 11:08Мне кажется или STM32F103 серию убили? По крайней мере доступность этих чипов оставляет желать лучшего, как и цены на них.
Прекрасно понимаю, что никто не будет переписывать код, который был написан на CMSYS много лет назад под них.
Но может кто-то подскажет, на что лучше переехать с F103C8 серии? Сейчас присматриваюсь к G0, но пугает то, что они новые и по ним нет ERRATA и накопленного опыта...STMshchik Автор
14.10.2021 19:16Сам еще разбираюсь с этим вопросом. Осталась с давних времен отладочная с f103. Брал недавно как временный вариант stm32f103c6, но флеш памяти там уже 32 кб. Да придется рано или поздно на другую серию перейти
order227
14.10.2021 22:41Сейчас все из продажи пропало в принципе, это общий дефицит. Если же речь об альтернативе, то много чего есть от NXP на Cortex-M33, у Microchip всякие dsPIC33 и подобные, у infineon есть xmc4100 и младше.
Andy_Big
15.10.2021 21:23Ее не убили. Это полупроводниковый кризис, который зародился еще почти год назад.
Andy_Big
15.10.2021 21:34+1Я начинал с обновления прошивки по CDC. Но потом перешел на HID из-за отсутствия необходимости устанавливать драйвера :)
Да, нужно свое приложение, но это не проблема. У меня приложение в трех вариантах:
- пользовательский - позволяет выбрать вариант прошивки только из совместимых с подключенным девайсом и только обновить прошивку;
- сервисный - позволяет прошить любой вариант в любой девайс, и только обновление прошивки;
- производственный: позволяет прошить любой вариант, назначить серийный номер, внести данные об устройстве в базу данных, считать EPROM;Скриншот
Все варианты прошивки сидят прямо в исполняемом файле, то есть не нужно качать отдельно саму прошивку и отдельно приложение. Скачал, запустил, прошил :)
Ну и да, сами прошивки в зашифрованном виде, загрузчик, принимая их от приложения, расшифровывает.
Так же сделал свой пакетный протокол по принципу "запрос-ответ". Содержимое каждого пакета проверяется при получении на целостность.
nordfox
Интересное решение. А чего не прикинуться sd картой? Да, чуть сложнее, зато прошивальщик не нужен. Хотя, если взять готовое решение FS, то все решаемо.
STMshchik Автор
Да, можно. Где-то такое уже видел. Да и про USB CDC загрузчик тоже видел на англоязычном ютубе, только там через Arduino IDE прошивают. У меня есть устройство, в котором связка МК+микросхема Flash памяти. И неудобно по отдельности прошивать МК и память, убирать перемычки с микросхемы памяти, подключать два программатора. И вот захотелось сделать загрузчик, который за один присест прошьет и МК, и память. Сейчас загрузку в МК реализовал, далее собираюсь добавлять поддержку прошивки памяти.
riuson
Для CDC нужен драйвер и приложение. Для HID - приложение. Для MSC - ничего.
Один присест (почти) сделать легко - два файла на виртуальной ФС. Один - память МК, другой - внешняя память.
Если интересно, могу показать.
STMshchik Автор
В принципе можно сделать установочный файл, который будет и драйвера ставить, и приложение ставить. Но то, что для Mass Storage ничего не нужно весомый аргумент
ionicman
Очень бы хотелось увидеть реализацию.
riuson
github
Sap_ru
Видел один CDC который можно было прошить отправив hex-файл в устройство.
andreykorol
Поддерживаю, делал такое. Только эмуляция не "sd-карты", а usb massstorage. Размеры флеша не большие - fat12, насколько я помню, эмулировал. Вход в бутлоадер: по значению backup-регистра, нескольким перезагрузкам по wdt подряд или по отсутствию прошивки в районе основного приложения. Если включена защита от чтения, то отдаешь сектора заполненные 0xFF при чтении области основного приложения.
nordfox
sd-карты так это я задал направление мысли)
COKPOWEHEU
С CDC же проще: драйвера в системе обычно уже есть, а для заливки достаточно cat file.bin > /dev/ttyACM0. Правда, в статье описан более сложный способ с полноценным командным обменом.