Но надо еще его дорабатывать + заготовка для протокола приема (не работает скорее всего, просто из чатгпт вставил) |
||
---|---|---|
Core | ||
Drivers | ||
MDK-ARM | ||
.gitignore | ||
.mxproject | ||
README.md | ||
uksvep_2_2_v1.ioc |
STM32 Bootloader (Beta)
Описание
Этот бутлоадер для STM32 реализован как машина состояний (state machine).
Его задача — управлять обновлением прошивки по UART или CAN, а также обеспечивать безопасный переход между приложением и бутлоадером.
Общение с бутлоадером
В гите есть терминалка на C# для общения с бутом через SlCan (uart там не сделан). А вообще реализованы следующие команды
0x01
— стирание прошивки во Flash — (CMD_ERASE
)0x02
— запуск процедуры приёма страницы — (CMD_START_RECEIVE
)0x03
— запись блока прошивки — (CMD_WRITE
)0x04
— переход в приложение — (CMD_GOTOAPP
)0x05
— сброс микроконтроллера — (CMD_RESET
)0x06
— принудительный переход в бутлоадер — (CMD_GOTOBOOT
)0xAA
— проверка связи (ping) — (CMD_PING
)
Бутлоадер уже содержит каркас для работы как с CAN (и некоторые наработки для UART, но не проверенные).
Для расширения функционала и поддержки новых протоколов нужно доопределить следующие функции.
- Приём команды:
BootloaderCommand_t Bootloader_UART_Receive(Bootloader_t *bl); //boot_uart.c BootloaderCommand_t Bootloader_CAN_Receive(Bootloader_t *bl); //boot_can.c
- Читает 1 байт команды и возвращает её (
CMD_ERASE
,CMD_WRITE
, и т.п.) или, если нет команды,NO_CMD
.
- Читает 1 байт команды и возвращает её (
- Приём страницы прошивки:
void Bootloader_UART_Receive_Page(Bootloader_t *bl); //boot_uart.c void Bootloader_CAN_Receive_Page(Bootloader_t *bl); //boot_can.c
- Принимает блок данных длиной
PAGE_SIZE
байт. - Принимает CRC32 (4 байта).
- Заполняет поля
bl->fw_buffer
,bl->fw_len
,bl->fw_crc
.
- Принимает блок данных длиной
Как работает бутлоадер
- После сброса бутлоадер проверяет сохранённые ошибки и "ключ" прошивки.
- Если приложение корректное — выполняется переход в него.
- Если приложение повреждено или нет ключа — остаётся в бутлоадере.
- В состоянии
IDLE
бутлоадер слушает команды. - Прошивка отправляется страницами, каждая страница проверяется по CRC32.
- По завершению записи устанавливается "ключ приложения", и возможен переход в основное приложение.
- При ошибках — возврат в состояние
ERROR
, уведомление хоста и мигание LED. Для сброса ошибок надо перезапустить МК.
Основные особенности бута
- Реализован как конечный автомат со следующими состояниями:
INIT
— проверка ключа, и далее переход в приложение или инициализация бутаIDLE
— ожидание командыRECEIVE_UART
/RECEIVE_CAN
— приём страницы прошивкиWRITE
— запись принятой страницы во FlashERASE
— стирание приложенияJUMP_TO_APP
— переход к основному приложениюJUMP_TO_BOOT
— возврат в бутлоадерRESET
— программный сбросERROR
— обработка ошибок
- Проверка целостности прошивки с помощью CRC32
- Учёт ошибок (hardfault, memmanage, watchdog и т.п.)
- Индикация состояния через LED:
- мигает раз в 500 мс при ошибке
- включается при приеме комады и выключается, когда команда выполнена
Интеграция в проект
Здесь бутлоадер и основное приложение реализованы как отдельные таргеты:
-
Таргет приложения
Исключаетmain()
бутлоадера и компилирует только само приложение.
Адрес загрузки приложения:0x0800C000
. -
Таргет бутлоадера
Исключает код приложения и компилирует только бутлоадер.
Адрес загрузки бутлоадера:0x08000000
.
Чтобы в основном приложении можно было управлять бутлоадером:
- Подключить
boot_jump.h
иboot_jump.c
для взаимодействия с бутлоадером:
#include "boot_jump.h"
- В начале
main()
вызватьApp_Init()
, чтобы установить VTOR на начало приложения:
App_Init();
- Для перехода в бутлоадер (например, при ошибке или обновлении):
JumpToBootloader();