Обеспечь единый процесс обновления для STM32F103/F407/G474 и TMS320F2812/F28335: discovery, служебные ответы, BUSY, тайм-аут сессии и подтверждение приложения. Добавь самостоятельные проекты CCS, аппаратные хранилища и Python-клиент. Совместимость: структуры конфигурации и порта расширены, поэтому потребители должны пересобраться и обнулить новые поля. Для C28x callbacks используют pcan_boot_byte_t; периодический pcan_boot_poll обслуживает discovery и настроенный тайм-аут.
110 lines
10 KiB
Markdown
110 lines
10 KiB
Markdown
# STM32: общий слой ProtoCAN Boot v1
|
||
|
||
Порты [F103C8](../stm32f103/README.md), [F407VE](../stm32f407/README.md) и
|
||
[G474VE](../stm32g474/README.md) подключают bxCAN/FDCAN и Flash к текущему `pcan_boot`.
|
||
F103/F407 предоставляют как лёгкий CMSIS boot main для существующих проектов,
|
||
так и независимый HAL-порт. G474 использует HAL FDCAN/Flash.
|
||
`pcan_boot_stm32.inc` включается семейным `.c`; отдельно его компилировать не надо.
|
||
Сохраните рядом каталоги `stm32-common` и нужного семейства.
|
||
|
||
Reusable `pcan_boot_stm32*.c` не содержит `main` или startup. Готовые `boot_main.c`
|
||
и вход из приложения находятся в семейных каталогах. Для F103/F407 общая
|
||
CMSIS-реализация транспорта, callbacks и безопасного handoff — `boot_native.inc`;
|
||
G474 также содержит `boot_startup.c` для исходных Keil/GCC-сборок.
|
||
Тактирование платы, linker и привязка USB/CAN-приложения остаются в проектах.
|
||
|
||
KONOR, climate и CANdle G474 уже подключены через свои submodule: локальные
|
||
boot main/control заменены include-обёртками, состав Keil/CMake обновлён.
|
||
UART использует общий `rs485-boot` с сохранением SETGUI v1 wire-протокола.
|
||
[Схема подключённых проектов и проверки сборок](../../projects/STM32.md).
|
||
|
||
## Подключение reusable HAL-портов F103/F407
|
||
|
||
1. Добавьте в сборку `src/pcan_boot.c` и семейный `pcan_boot_stm32f103.c`
|
||
либо `pcan_boot_stm32f407.c`; в include paths — `include`, каталог порта,
|
||
CMSIS, HAL и каталог вашего `stm32f1xx_hal_conf.h` / `stm32f4xx_hal_conf.h`.
|
||
2. В HAL включите CAN, FLASH, RCC, GPIO и CORTEX. Выполните `HAL_Init`, настройте
|
||
тактирование, SysTick и GPIO, вызовите `HAL_CAN_Init` для CAN1. Настройка скорости
|
||
шины принадлежит проекту; исходные устройства используют 500 кбит/с.
|
||
3. Выделите CAN1, FIFO0 и банки фильтров 0/1 загрузчику. Перед вызовом init CAN
|
||
должен находиться в состоянии READY, без чужих активных фильтров. Init настраивает
|
||
адресный фильтр и broadcast discovery, затем вызывает `HAL_CAN_Start`.
|
||
Оба приоритета ProtoCAN разрешены, standard и remote кадры отвергаются.
|
||
4. Не включайте CAN TX/RX IRQ для этого handle и не отправляйте через него кадры
|
||
из других контекстов: порт использует опрос и сам читает TXOK до reset.
|
||
5. Вызывайте семейный `poll` из основного цикла только после успешного init.
|
||
Стирание Flash выполняется синхронно; вызов из IRQ не допускается.
|
||
6. Linker приложения, VTOR и переход после reset должны соответствовать карте
|
||
выбранного профиля. Изменение адресов требует отдельного согласования
|
||
геометрии стирания, linker и host-клиента.
|
||
|
||
Пример для F103; `hcan` уже инициализирован проектом:
|
||
|
||
```c
|
||
#include "pcan_boot_stm32f103.h" /* Подключает HAL-порт и текущий API общего автомата. */
|
||
static pcan_boot_stm32_t updater; /* Сохраняет состояние между итерациями главного цикла. */
|
||
static bool start_updater(CAN_HandleTypeDef *hcan) /* Вызывается после настройки CAN1, clock tree, GPIO и SysTick. */
|
||
{ /* Настройка идентичности прибора не зависит от аппаратной геометрии Flash. */
|
||
pcan_boot_config_t config = {0}; /* Не зависит от порядка полей расширяемого API. */
|
||
config.device_type = 7U; /* Пример: тип 7 должен совпадать с выбранным адресом в клиенте прошивки. */
|
||
config.device_id = 13U; /* Пример: номер 13 повторяет исходный адрес загрузчика KONOR. */
|
||
config.ack_window = 16U; /* Подтверждает каждые 16 CAN-блоков по восемь байт. */
|
||
config.session_timeout_ms = 30000U; /* Пример: 30 секунд без активности прерывают RAM-сессию. */
|
||
return pcan_boot_stm32f103_init(&updater, hcan, &config); /* Настраивает single-slot геометрию, фильтры 0/1 и запускает CAN. */
|
||
} /* После успеха основной цикл регулярно вызывает pcan_boot_stm32f103_poll(&updater). */
|
||
```
|
||
|
||
Product/HW/FW в примере равны нулю; для изделия задайте их явно и согласуйте
|
||
с manifest клиента. Порт сохраняет `ack_window` и `session_timeout_ms`, но сам
|
||
задаёт `active_slot=0`, `slot_count=1`, `max_image_size` по физическому профилю.
|
||
Конфигурацию `config` можно создавать на стеке; состояние `updater` и `hcan`
|
||
должно существовать всё время работы загрузчика.
|
||
|
||
## Flash, подтверждения и reset
|
||
|
||
- Запись последовательная, блоки по восемь байт; неполная аппаратная единица
|
||
допустима только в конце образа и дополняется `FF`. CRC учитывает полезную длину.
|
||
- HAL-ошибки и readback каждого слова проверяются; после erase/program Flash
|
||
снова блокируется, включая обработанные отказы. На F407 перед readback
|
||
вызывается `FLASH_FlushCaches`, чтобы соседние записанные слова не читались
|
||
из устаревшей строки Flash-кэша; состояние включения кэшей сохраняется HAL.
|
||
- VERIFY перечитывает Flash, сравнивает её CRC и проверяет MSP/Thumb reset vector.
|
||
Точка входа должна принадлежать фактическому образу, MSP — основной SRAM,
|
||
с выравниванием восемь байт. CCM F407 в данном профиле для стека не используется.
|
||
- COMMIT повторно проверяет образ и устанавливает признак в RAM.
|
||
REBOOT разрешён только в состоянии COMMITTED. Ответ перед reset должен
|
||
завершиться с TXOK; отсутствие mailbox, ошибка шины или тайм-аут 100 мс
|
||
не вызывают reset. Для этого HAL tick должен работать при ожидании TX.
|
||
- BUSY перед стиранием, между секторами F407 и после erase сохраняет активность
|
||
сессии. На однобанковой Flash код не исполняется во время аппаратного стирания;
|
||
непрерывные ответы в этот интервал не гарантируются. Настройте тайм-аут клиента
|
||
больше максимального времени стирания одной аппаратной операции.
|
||
|
||
## Запуск приложения и потеря питания
|
||
|
||
Порт не меняет Option Bytes, защиту секторов и VDD; F407 требует 2,7..3,6 В
|
||
для программирования x32. Переход из работающего приложения в загрузчик,
|
||
backup/SRAM-флаг запроса, отключение периферии и безопасная замена MSP
|
||
остаются в `main` и startup устройства.
|
||
|
||
`*_vectors_valid()` проверяет только векторы и диапазоны. После внешнего reset
|
||
этого недостаточно для доказательства целостности образа: RAM-признак COMMIT
|
||
потерян, а частично записанное приложение уже может иметь корректные векторы.
|
||
Эти профили сохраняют исходную single-slot модель без постоянных метаданных,
|
||
rollback, resume после питания и аутентификации. Для защищённого запуска
|
||
проекту нужен отдельный постоянный manifest с полной проверкой образа.
|
||
|
||
## Проверка
|
||
|
||
`python tests/run_tests.py` из корня `protocan-boot` запускает три production-порта
|
||
с моделью HAL и Flash, наряду с существующими проверками ядра и TI-портов.
|
||
Можно также использовать обычные CMake/CTest: цели `test_stm32f103`,
|
||
`test_stm32f407`, `test_stm32g474` работают на Windows и POSIX.
|
||
|
||
Проверяются все хвосты CAN-блока, полный ERASE/DATA/VERIFY/COMMIT/REBOOT,
|
||
повреждение readback, отказы HAL/TX, фильтрация RX и сохранность памяти
|
||
перед приложением и за верхней границей; для G474 проверяются оба DBANK-режима,
|
||
переход между банками, запрет swap, ёмкость Flash и старое shifted-DLC HAL.
|
||
Эти тесты не заменяют проверку
|
||
на реальной плате с её linker, питанием, трансивером и SysTick.
|