Files
templates/c/protocan-boot/docs/BOOTLOADER.md

8.2 KiB
Raw Blame History

ProtoCAN Boot Protocol

Статус: Draft
Версия протокола: 1.0
Совместимость: classic CAN 2.0B, Extended ID, DLC 0…8
Реализация: templates/c/protocan-boot

Назначение

Сервис обновляет адресованный прибор по CAN и поддерживает два логических слота A/B. Активный слот не стирается: новый образ записывается в неактивный, проверяется и атомарно назначается кандидатом на запуск.

Карта сообщений

MsgType Имя MsgBody Payload
0x9 BOOT_CONTROL SessionID[15:8] | Command[7:0] параметры команды
0xA BOOT_DATA_A BlockIndex[15:0] 8 байт слота A
0xB BOOT_DATA_B BlockIndex[15:0] 8 байт слота B
0xC BOOT_STATUS SessionID[15:8] | Command[7:0] статус и прогресс
0xD BOOT_DISCOVERY подтип ответа идентификация

Все команды записи адресуются конкретному DeviceType/DeviceID и имеют Route=0. Ответы сохраняют адрес прибора и имеют Route=1.

Адресация образа

MsgBody кадра данных — номер 8-байтового блока:

offset = (uint32_t)BlockIndex * 8U;
address = SLOT_X_BASE + offset;
512 КиБ = 524 288 байт
524 288 / 8 = 65 536 блоков
BlockIndex = 0x0000…0xFFFF
BlockIndex Смещение Диапазон байтов
0x0000 0x00000 0x00000…0x00007
0x0001 0x00008 0x00008…0x0000F
0xFFFF 0x7FFF8 0x7FFF8…0x7FFFF

0x80000 является первой позицией за границей слота. Последний кадр дополняется 0xFF, но CRC32 вычисляется только по ImageSize байтам.

Команды BOOT_CONTROL

Код Команда DLC Payload Допустимое состояние
0x01 IDENTIFY 0 отсутствует любое
0x02 ENTER_BOOT 0 отсутствует любое; SessionID != 0
0x03 BEGIN_IMAGE 8 размер и CRC32 metadata
0x04 BEGIN_COMPAT 8 совместимость и версия metadata
0x05 ERASE 0 отсутствует ready-to-erase
0x06 VERIFY 0 отсутствует образ получен
0x07 COMMIT 0 отсутствует verified
0x08 CONFIRM 0 отсутствует запущенное приложение
0x09 REBOOT 0 отсутствует активная сессия
0x0A ABORT 0 отсутствует активная сессия
0x0B QUERY_PROGRESS 0 отсутствует активная сессия

BEGIN_IMAGE

DATA[0..3] ImageSize, uint32 little-endian
DATA[4..7] ImageCRC32, uint32 little-endian

BEGIN_COMPAT

DATA[0..1] ProductType, uint16 little-endian
DATA[2]    HardwareRevisionMin
DATA[3]    HardwareRevisionMax
DATA[4..7] FirmwareVersion, uint32 little-endian

До ERASE прибор обязан получить обе части метаданных и проверить размер, тип изделия, аппаратную ревизию, версию и политику anti-rollback.

BOOT_STATUS

MsgBody[15..8] SessionID
MsgBody[7..0]  команда, на которую дан ответ

DATA[0]        Status
DATA[1]        TargetSlot: 0=A, 1=B, 0xFF=не выбран
DATA[2..3]     NextBlock, uint16 little-endian
DATA[4..7]     RunningCRC32, uint32 little-endian
Код Статус Повтор допустим
0x00 OK
0x01 BUSY да, после задержки
0x02 INVALID_COMMAND после исправления
0x03 WRONG_DEVICE нет для этого образа
0x04 WRONG_HARDWARE нет для этого образа
0x05 INVALID_SIZE нет для этого образа
0x06 CRC_ERROR новая передача
0x07 FLASH_ERROR зависит от платформы
0x08 SEQUENCE_ERROR да, с NextBlock
0x09 SIGNATURE_ERROR нет
0x0A SESSION_ERROR открыть новую сессию
0x0B VOLTAGE_ERROR да после нормализации питания
0x0C INVALID_STATE выполнить правильный переход

State machine

IDLE
  └─ ENTER_BOOT ─> METADATA
                     ├─ BEGIN_IMAGE
                     └─ BEGIN_COMPAT
                            │
                            v
                    READY_TO_ERASE
                            │ ERASE
                            v
                      RECEIVING
                            │ VERIFY
                            v
                       VERIFIED
                            │ COMMIT
                            v
                    PENDING + REBOOT
                            │ CONFIRM
                            v
                       CONFIRMED

Ошибка Flash, CRC, совместимости или подписи переводит сессию в FAILED. Новая ENTER_BOOT создаёт чистую сессию. ABORT прекращает текущую передачу, не активируя частично записанный слот.

Надёжность и повторы

  • Блоки передаются строго по возрастанию BlockIndex.
  • Дубликат или пропуск возвращает SEQUENCE_ERROR и ожидаемый NextBlock.
  • Базовый режим подтверждает каждый блок.
  • Рабочий режим может подтверждать окно из 16 блоков.
  • После потери связи QUERY_PROGRESS возвращает следующий ожидаемый блок, пока состояние загрузчика сохранено.
  • Для продолжения после перезагрузки порт должен сохранять session metadata и восстановить её при инициализации; ядро версии 1.0 само это не делает.

Безопасность и A/B-обновление

active=A -> target=B -> verify -> pending=B
active=B -> target=A -> verify -> pending=A

CRC32 защищает только от случайного повреждения. Серийный загрузчик должен дополнительно проверить подпись контейнера, границы вектора, совместимость и anti-rollback. Bootloader не обновляется командами BOOT_DATA_A/B.

Boot metadata должна атомарно хранить:

  • активный слот;
  • pending-слот;
  • подтверждение запуска;
  • число неудачных попыток;
  • версию и CRC32 образа.

Если приложение не выполняет CONFIRM за установленное число запусков, загрузчик возвращается к предыдущему подтверждённому слоту.

Эталонный сценарий

  1. ПМ адресно отправляет IDENTIFY.
  2. ПМ открывает ненулевой SessionID командой ENTER_BOOT.
  3. ПМ отправляет BEGIN_IMAGE и BEGIN_COMPAT.
  4. Прибор сообщает выбранный неактивный слот.
  5. ПМ выполняет ERASE и передаёт BOOT_DATA_A либо BOOT_DATA_B.
  6. ПМ выполняет VERIFY, затем COMMIT и REBOOT.
  7. Новое приложение после самопроверки выполняет CONFIRM.