При проектировании устройства на микроконтроллере бывает встает вопрос об обновлении прошивки прибора. Причем сам процесс обновления прошивки должен быть простым и доступным для обыкновенного пользователя. И конкретно для микроконтроллера STM32F103C8 возможна загрузка прошивки по UART. То есть к схеме необходимо добавлять микросхему конвертера USB-UART. Либо воспользоваться аппаратными возможностями USB микроконтроллера, что я и сделал. Меня заинтересовал вопрос о возможности обновления прошивки по USB. На некоторых МК даже есть аппаратный USB-загрузчик, но только не на STM32F103C8, поэтому пришлось все программно реализовывать. По программной части для STM32 существует USB Library от STMicroelectronics с реализованными классами USB и примерами. В частности заинтересовал класс DFU т.е. загрузка прошивки по USB. В данном классе уже реализован свой набор команд для взаимодействия МК и приложения на ПК "STM32CubeProgrammer". Но мне хотелось что-то своё, кастомное и неограниченное данным набором команд. И пришла мысль "А почему бы не реализовать всё это в классе CDC?". Тут и размер загрузчика примерно таким же оказался, но главное можно реализовать свой набор команд, работать на ПК с последовательным портом и соответственно понятнее, как написать приложение для ПК. У меня есть небольшой опыт написания приложений с использованием библиотеки QT на С++, поэтому с ее помощью была создана программа для USB загрузчика.  Рассмотрим работу и настройку самого загрузчика на МК. Проект создан в STM32CubeIDE, размер загрузчика получился 15 кБ. В файле main.c есть условие при котором МК работает в режиме загрузчика, либо управление передается пользовательскому приложению: Мы можем по желанию задать любое условие входа в режим загрузчика, в моем случае нужно замкнуть ножку В0 на землю при загрузке МК. И тогда МК перейдет в режим загрузчика и при подключении по USB на стороне ПК будет определяться как виртуальный COM порт. В ином случае будет выполняться основная прошивка. В файле Memory.h заданы адреса начала основной прошивки и конца памяти программ: Теперь подготовим пользовательскую прошивку к загрузке. Для примера возьмем простое моргание светодиодом. В проекте для CubeIDE в файле STM32F103C8TX_FLASH.ld нужно изменить адрес начала выполнения программы на 0х8003С00: В файле system_stm32f1xx.c задать смещение таблицы векторов 0х3С00: Теперь можно перейти к загрузке данной прошивки. Ставим перемычку на ножке B0 и подключаем по USB плату. Запускаем приложение "USB CDC Программатор": Для поиска доступных COM портов нажимаем "Обновить", в списке выбираем появившийся порт и нажимаем "Подключить". Выдаст сообщение об успешном подключении платы и название кнопки подключения изменится на "Отключить": Если до этого в плату была загружена другая прошивка, то ее необходимо удалить, нажав на "Стереть". При этом затирается вся область памяти начиная с адреса 0х8003С00 и до конца памяти программ. Далее нажимаем "Открыть" и в диалоговом окне выбираем файл прошивки в формате .bin (Пока поддерживается только такой формат файлов). В таблице появляются данные прошивки, в логах название и размер файла. Нажимаем "Загрузить" и через некоторое время прошивка будет загружена: Теперь можно отключить плату, убрать перемычку и убедиться в работоспособности прошивки. При необходимости возможно считать прошивку и сохранить ее в файле на компьютере. Считывание памяти МК происходит начиная с адреса 0х8003С00 и до первого числа 0хFFFFFFFF. К статье прикладываю: Проект в CubeIDE  Исходники "USB CDC Программатор" Приложение "USB CDC Программатор" для Windows