Но надо еще его дорабатывать + заготовка для протокола приема (не работает скорее всего, просто из чатгпт вставил)
96 lines
5.8 KiB
Markdown
96 lines
5.8 KiB
Markdown
# 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();
|
||
```
|