Однобанковый загрузчик с двумя слотами под прошивки. Управляется по UART через CLI-утилиту boot с использованием протокола BCP. Поддерживает запись, верификацию и запуск образов.
- Оглавление
- Возможности
- Карта памяти
- Управление
- Подготовка прошивки
- Передача управления приложению
- Ограничения
- Документация
- Хранение до двух прошивок одновременно в независимых слотах по 48 КБ
- Верификация образа по CRC32/ISO-HDLC и магическому числу
- Получение версии загрузчика и метаданных образов
- Запись прошивки во флеш по протоколу FWP
| Регион | Адрес начала | Размер |
|---|---|---|
| Bootloader | 0x08000000 |
20 КБ |
| Слот 1 | 0x08005000 |
48 КБ |
| Слот 2 | 0x08011000 |
48 КБ |
Каждый слот начинается с заголовка образа размером 512 байт. Сразу за заголовком располагается тело прошивки, начиная с vector table.
Загрузчик работает по UART1 (PA9 TX, PA10 RX) с параметрами 115200 8N1, без управления потоком. После сброса загрузчик инициализируется и ожидает команд по протоколу BCP — асинхронному протоколу запрос/ответ. Передача тела прошивки в слот выполняется по протоколу FWP (свой аналог YMODEM) поверх того же UART.
Для управления используется CLI-утилита boot. Она инкапсулирует BCP и FWP и предоставляет команды записи, верификации, запуска и получения версии.
Полное описание протокола и сущностей:
Чтобы загрузчик мог запустить прошивку, она должна:
- Быть собрана для запуска с адреса слота (
0x08005000для слота 1). - Содержать заголовок образа в первых 512 байтах.
- Быть пропатчена скриптом
metadata.pyпосле получения.bin— он проставит фактические размер и CRC.
В MEMORY указывается начало слота и его длина:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x08005000, LENGTH = 48K
}В SECTIONS первой секцией размещается .image_metadata фиксированной длиной 512 байт. Сразу за ней должна идти .isr_vector:
SECTIONS
{
.image_metadata :
{
. = ALIGN(4);
__image_metadata_start = .;
KEEP(*(.image_metadata))
FILL(0x00);
. = __image_metadata_start + 512;
} >FLASH
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
/* остальные секции */
}Порядок важен: загрузчик при запуске вычисляет адрес vector table как адрес слота + 512, поэтому ничего, кроме заголовка, перед .isr_vector быть не должно.
Структура заголовка соответствует определению в загрузчике:
#define IMAGE_METADATA_SIZE (512u)
typedef struct __attribute__((packed)) {
uint32_t magic;
uint32_t size;
uint32_t crc;
uint8_t version_major;
uint8_t version_minor;
uint8_t version_patch;
uint8_t reserved[IMAGE_METADATA_SIZE - 15];
} image_metadata_t;В прошивке необходимо объявить переменную этого типа и поместить её в секцию .image_metadata через атрибут:
__attribute__((section(".image_metadata")))
const image_metadata_t metadata = {
.magic = 0xAAAAAAAAu,
.version_major = 1,
.version_minor = 0,
.version_patch = 0,
};Поля size и crc на этапе компиляции инициализируются нулями — их проставляет metadata.py после сборки, поэтому их можно не заполнять.
Поле magic обязано быть 0xAAAAAAAA, иначе образ будет признан невалидным.
metadata.py принимает на вход финальный .bin, проверяет магическое число в первых 4 байтах, считает CRC32/ISO-HDLC от тела образа (всех байт после 512-байтового заголовка) и записывает размер тела и CRC по фиксированным смещениям заголовка.
Интеграция в Makefile:
PYTHON ?= python3
PATCH_SCRIPT := tools/metadata.py
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(PYTHON) $(PATCH_SCRIPT) $@После этого .bin готов к загрузке через boot flash.
Запуск прошивки из выбранного слота выполняется по команде BCP RUN. Загрузчик:
- Вычисляет адрес тела образа как
адрес слота + 512. - Считывает по этому адресу начальное значение MSP и адрес
Reset_Handler(стандартный заголовок Cortex-M vector table). - Отключает прерывания, переставляет
SCB->VTORна тело образа, включает прерывания. - Устанавливает MSP и передаёт управление на
Reset_Handlerприложения.
Прошивка должна корректно отрабатывать ситуацию, когда она запускается не с нулевого адреса флеша — в первую очередь правильно настраивать VTOR (если переопределяет его повторно) и не делать предположений о состоянии периферии после сброса, поскольку до запуска приложения работал загрузчик.
- Поддерживается только STM32F103 (Cortex-M3, arm-none-eabi-gcc).
- Максимальный размер образа — 48 КБ, включая заголовок 512 байт.
- Заголовок образа имеет фиксированный размер 512 байт;
- Возврат из приложения в загрузчик возможен только через перезагрузку питания
- BCP — протокол управления
- Терминология
- CLI-утилита
boot