# STM32 Bootloader (Beta) ## Описание Этот бутлоадер для STM32 реализован как **машина состояний (state machine)**. Его задача — управлять обновлением прошивки по UART или CAN, а также обеспечивать безопасный переход между приложением и бутлоадером. --- ## Общение с бутлоадером В [гите](https://git.arktika.cyou/Razvalyaev/boot_terminal) есть терминалка на 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**, но не проверенные). Для расширения функционала и поддержки новых протоколов нужно доопределить следующие функции. - Приём команды: ```c 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`. - Приём страницы прошивки: ```c 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`. --- ## Как работает бутлоадер 1. После сброса бутлоадер проверяет сохранённые ошибки и "ключ" прошивки. - Если приложение корректное — выполняется переход в него. - Если приложение повреждено или нет ключа — остаётся в бутлоадере. 2. В состоянии `IDLE` бутлоадер слушает команды. 3. Прошивка отправляется страницами, каждая страница проверяется по CRC32. 4. По завершению записи устанавливается "ключ приложения", и возможен переход в основное приложение. 5. При ошибках — возврат в состояние `ERROR`, уведомление хоста и мигание LED. Для сброса ошибок надо перезапустить МК. --- ## Основные особенности бута - Реализован как конечный автомат со следующими состояниями: - `INIT` — проверка ключа, и далее переход в приложение или инициализация бута - `IDLE` — ожидание команды - `RECEIVE_UART` / `RECEIVE_CAN` — приём страницы прошивки - `WRITE` — запись принятой страницы во Flash - `ERASE` — стирание приложения - `JUMP_TO_APP` — переход к основному приложению - `JUMP_TO_BOOT` — возврат в бутлоадер - `RESET` — программный сброс - `ERROR` — обработка ошибок - Проверка целостности прошивки с помощью **CRC32** - Учёт ошибок (hardfault, memmanage, watchdog и т.п.) - Индикация состояния через LED: - мигает раз в 500 мс при ошибке - включается при приеме комады и выключается, когда команда выполнена --- ## Интеграция в проект Здесь бутлоадер и основное приложение реализованы как отдельные таргеты: - **Таргет приложения** Исключает `main()` бутлоадера и компилирует только само приложение. Адрес загрузки приложения: `0x0800C000`. - **Таргет бутлоадера** Исключает код приложения и компилирует только бутлоадер. Адрес загрузки бутлоадера: `0x08000000`. Чтобы в основном приложении можно было управлять бутлоадером: 1. Подключить `boot_jump.h` и `boot_jump.c` для взаимодействия с бутлоадером: ```c #include "boot_jump.h" ``` 2. В начале `main()` вызвать `App_Init()`, чтобы установить VTOR на начало приложения: ```c App_Init(); ``` 3. Для перехода в бутлоадер (например, при ошибке или обновлении): ```c JumpToBootloader(); ```