Files
templates/c/protocan-boot/ports/tms320f28335/README.md
T
Andrey c6390ae1c9 feat(protocan-boot): Добавь порты MCU и сервисы загрузки
Обеспечь единый процесс обновления для STM32F103/F407/G474 и TMS320F2812/F28335: discovery, служебные ответы, BUSY, тайм-аут сессии и подтверждение приложения. Добавь самостоятельные проекты CCS, аппаратные хранилища и Python-клиент.

Совместимость: структуры конфигурации и порта расширены, поэтому потребители должны пересобраться и обнулить новые поля. Для C28x callbacks используют pcan_boot_byte_t; периодический pcan_boot_poll обслуживает discovery и настроенный тайм-аут.
2026-10-23 14:16:19 +03:00

208 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# F28335 + M95M02: CAN, отдельный загрузчик и A/B
Реализация состоит из Flash-загрузчика `projects/ccs/f28335`, переносимого
`f28335_boot_store.c`, аппаратного `f28335_boot_hw.c` и адаптера
`f28335_can_boot.c`. Приложение подключает общий `f28335_can_application.c`
прямой ссылкой linked resource из templates в CCS Debug/Release.
В сборке `EEPROM_M95M02=0` CAN Boot отключён. Для установленной M95M02 — значение 1.
## Адрес и формат
Адрес определяется физическим номером **PERIPH 0–31** по новой Excel-таблице:
Type = 1 + PERIPH / 16 (целая часть), Device ID = PERIPH mod 16.
**УМП1 — 1/5, УМП2 — 1/6, задатчик — 1/8**. Product **0x2833**, HW **1**
описывают существующую аппаратную совместимость F28335 и не являются CAN-адресом.
Имена паспорта для назначенных плат — `UMP1`, `UMP2`, `Zadatchik`.
Приложение передаёт Mode в `F28335CanBoot_Init(Mode)`. Загрузчик независимо
читает те же активные низким уровнем GPIO21/20/22/51 с весами 1/2/4/8 и базой 1.
Поэтому существующие перемычки ПМ35 задают номера 1–16; номера 0 и 17–31
поддерживаются адресным контрактом, но требуют другого источника физического номера.
Общий адрес 3/7 больше не принимается. Чужие адреса отбрасываются аппаратным
mailbox, ISR и ядром до записи EEPROM, включая данные A/B и управляющие команды.
В приложении FW берётся из `firmware_version.h`, формат `major<<24 | minor<<16 | patch`;
для версии 1.1.2 это `0x01010002`. Загрузчик сообщает версию подтверждённого образа
из журнала, при отсутствии такого образа — 0. Версия кандидата передаётся в BEGIN_COMPAT.
CAN **250000 бит/с**, Extended ID, окно **16 блоков по 8 октетов**.
Для задатчика и session=1: ENTER_BOOT `0x11890102`, STATUS `0x198C0102`.
## Общий запуск Flash и резервной EEPROM
Сектор A и аппаратный boot `0x33FFF6` принадлежат постоянному загрузчику.
Flash-приложение использует `[0x300000,0x338000)`: первые 16 слов — описание
FAB1, остальные — собственные LOAD-секции. `f28335_flash_app.c` проверяет
magic/version, entry, границы, инверсию entry, маркеры и CRC32 IEEE всего
диапазона после заголовка, включая промежутки, заполненные `0xFFFF`.
Python-контракт `python/protocan/f28335_flash.py` заполняет зарезервированные
32 октета COFF по смещению, подтверждённому TI OFD, после линковки.
Загрузчик даёт трёхсекундное окно CAN, затем запускает исправную внутреннюю
Flash в приоритете. Отсутствующая/повреждённая Flash ведёт к прежнему выбору
EEPROM A/B с trial/CONFIRM/rollback. ENTER_BOOT удерживает CAN recovery.
Handoff running=`0xFE` обозначает проверенную внутреннюю Flash; 0/1 — EEPROM
A/B, `0xFF` — отсутствие запущенного приложения. Flash-приложение обслуживает
PING и ENTER_BOOT, но не подменяет подтверждение EEPROM-кандидата.
Обновление EEPROM по CAN не меняет приоритет исправной Flash после reset.
RS Flash должен стирать только B–H, публиковать FAB1 после проверки остальных
данных и запрещать любые адреса сектора A. В SETGUI соответствующие JTAG
маски задаются явными TI `FlashSectorA..H`: A для установки boot, B–H для
приложения. Полное стирание чипа внешним программатором не ограничивается linker.
Старая самостоятельная Flash-сборка с codestart `0x33FFF6` несовместима с этим
размещением и не должна передаваться как обновление приложения.
Образ — SCI8 BIN (`AA 08`), чётная длина от 24 до **130560 байт** включительно.
Числа в протоколе little endian. Адреса внутри SCI8: сначала старшее 16-битное
слово, затем младшее; каждое слово little endian. В C28x `char` 16-битный,
поэтому `pcan_boot_byte_t` хранит октет в младших 8 битах.
## Разметка EEPROM, байтовые адреса
| Область | Начало | Конец включительно | Размер |
|---|---:|---:|---:|
| Журнал 0 | 0x00000 | 0x000FF | 256 |
| Журнал 1 | 0x00100 | 0x001FF | 256 |
| Slot A | 0x00200 | 0x1FFFF | 130560 |
| Slot B | 0x20000 | 0x3FDFF | 130560 |
| Резерв | 0x3FE00 | 0x3FEFB | 252 |
| Параметры | 0x3FEFC | 0x3FFFD | 258 |
| Последнее слово | 0x3FFFE | 0x3FFFF | 2 |
В каждой странице журнала первые 64 октета содержат magic `FAB2`, версию 1,
sequence, active/pending/attempted, два manifest, CRC32 первых 56 октетов и
commit marker в октетах 60..63. Сначала обнуляется marker запасной страницы,
затем записывается тело с проверкой чтением, последним — marker. Предыдущая
страница остаётся действующей до полной публикации новой. Выбор sequence
учитывает переполнение u32. После ошибки публикации журнал перечитывается;
ошибка чтения блокирует последующие записи.
## Сценарий обновления и отката
1. Приложение принимает ENTER_BOOT, останавливает управление нагрузкой, выставляет 4 мА и выдерживает
секундный STOP, затем сохраняет session в NOINIT RAM 0x50..0x57. Watchdog выполняет reset.
ACK ENTER_BOOT отправляет уже Flash-загрузчик; приложение ничего не стирает.
2. BEGIN_IMAGE/BEGIN_COMPAT проверяют размер, Product, HW и сессию. Неактивный
слот выбирается автоматически; при первом образе это A. ERASE инвалидирует
только его manifest. Полного стирания EEPROM не требуется.
3. Последовательные DATA_A/B записываются с немедленным readback. VERIFY
проверяет потоковый CRC32, CRC32 EEPROM и полную таблицу SCI8.
Разрешена загрузка только в CPU word RAM `[0x8000,0xE000)`: максимум 64 секции,
без пересечений, усечений и хвостовых данных; entry должен попасть в секцию.
Запись в Flash, периферию, стек, RAM загрузчика и handoff запрещена.
4. COMMIT повторно проверяет образ и публикует pending в журнале. Подтверждённый
слот сохраняется. Повтор COMMIT безопасен. REBOOT выполняется после физического
CAN ACK ответа. Потеря ACK/тайм-аут передачи отменяет запрос reset.
5. Перед первым запуском кандидата загрузчик сохраняет attempted=1, затем
проверяет и копирует SCI8 в RAM. Следующий reset без CONFIRM сбрасывает pending
и запускает прежний active. Если прежнего образа нет — остаётся CAN recovery.
6. Новое приложение включает watchdog в начале запуска. До подтверждения
прерывания не кормят watchdog вместо основного цикла. После READY, 100 проходов
main и 5 секунд выполняется автоматический CONFIRM. Неудача сохранения
подтверждения через 10 секунд прекращает кормление watchdog, вызывая откат.
Адресная команда CONFIRM с ненулевой session также разрешена после READY.
CONFIRM в загрузчике и до первого запуска кандидата отклоняется.
PING, IDENTIFY и паспорт доступны без ENTER_BOOT. QUERY_PROGRESS/ABORT привязаны
к сессии. Сессия в RAM истекает через 30 секунд без подходящих команд/данных.
После reset передачу начинают заново; параметры и подтверждённый образ остаются.
ABORT после COMMIT не отменяет опубликованный pending. Для его пробного запуска
можно открыть новую сессию и отправить REBOOT. Pending запрещено перезаписывать.
Повторы ENTER_BOOT, метаданных, ERASE до первого блока, VERIFY и COMMIT учитывают
потерю ответа. Broadcast никогда не разрешает запись.
## Сервисные команды
Запрос: MsgType=9, Body=`session<<8 | command`. IDENTIFY/PING/паспорт не требуют сессии.
Ответ паспорта: MsgType=D, Body=`page<<8 | command`, DLC=8.
| Код | Имя | DLC запроса | Ответ |
|---:|---|---:|---|
| 01 | IDENTIFY | 0 | Product:u16, HW:u8, protocol:u8, FW:u32; Body=1 |
| 0C | PING | 0 | protocol, state, active, target, session, slot_count, last_status, 0 |
| 0D | CAPABILITIES | 0 | flags:u32, slot_capacity:u32 |
| 0E | DEVICE_NAME | 1 (page) | 8 ASCII-октетов имени; последний фрагмент с NUL |
| 0F | MEMORY_INFO | 1 (page) | Страницы ниже |
MEMORY_INFO 0: EEPROM bytes:u32, page bytes:u16, mode:u8 (0 app/1 boot), running:u8.
Страница 1: адреса A:u32, B:u32. Страница 2: active, pending, attempted, storage_healthy,
session_timeout_ms:u32. Страница 3: parameters_offset:u32, parameters_bytes:u32.
Слот FF означает отсутствие образа/запущенного приложения.
CAPABILITIES bits 0..11: ping, discovery, identify, name, memory, A/B, confirm,
rollback, separate loader, session timeout, readback, SCI8 validation.
Приложение, запущенное старым SPI ROM без handoff загрузчика, сообщает только
базовые сервисы (0x1F) и отклоняет ENTER_BOOT.
Обнаружение: MsgType=D, Body=0, DLC=0, Route=0. Адресный запрос или общий
DeviceType=7/DeviceID=15. Ответ IDENTIFY приходит с адреса прибора через
`2*(1+16*DeviceType+DeviceID)` мс. При нескольких одинаковых адресах конфликт
остаётся: каждому физическому устройству нужен уникальный адрес.
Python API: `protocan.can_boot.CanBootServices` — запросы и разбор паспорта;
`CanBootTransfer` — загрузка. Кнопка «Пинг» доступна в режиме ProtoCAN Boot
окна прошивки SETGUI. Для ENTER/VERIFY/COMMIT клиент ждёт до 15 секунд.
## Аппаратная интеграция
MBOX3 — адресные входящие Boot; MBOX4 — ответы; MBOX6 — точный broadcast discovery.
MBOX0..2 сохраняют legacy/UMP, MBOX5 загрузчик не использует. ISR помещает сообщения
в очередь на 31 кадр. Чужие адреса, RTR и неподходящие типы отбрасываются до очереди.
При переполнении/потере mailbox сессия отменяется; повторная запись начинается заново.
SPI-драйвер загрузчика имеет ограничение ожидания байта и WIP, 24-битный адрес,
разбиение по страницам 256 байт и восстановление конфигурации SPI приложения.
Он работает только при остановленном Timer2. Обычный Seeprom_write приложения
ограничен областью параметров; старый RS EXTEND 0x44 запрещён для A/B.
Загрузчик исполняется из внутренней Flash A 0x338000..0x33FF7F, entry 0x33FFF6.
Его RAM — 0xE000..0xFFFF; стек — 0x400..0x7FF. Приложение M95M02 использует
0x8000..0xD7FF для кода, 0xD800..0xDFFF для констант/инициализации,
0xE000..0xFFFF для .ebss после перехода в C runtime. Linker резервирует
NOINIT handoff в обоих проектах. CAN не содержит операций записи внутренней Flash.
## Первичная установка
1. Собрать приложение с EEPROM_M95M02=1 и обновлённым F28335.cmd; получить SCI8 BIN.
Старые BIN/OUT автоматически не заменены. Приложение должно содержать интеграцию
READY/CONFIRM, иначе на следующем reset оно останется неподтверждённым кандидатом.
2. Собрать отдельный загрузчик TI C2000 COFF compiler:
`python c/protocan-boot/projects/build.py --device f28335 --compiler <путь-к-ti-cgt-c2000>`.
Результат — `projects/ccs/f28335/Debug/F28335_CAN_AB.out` и MAP.
3. Установить обновлённый OUT через JTAG и выбрать аппаратный Flash boot
согласно схеме платы. При переходе с общего адреса 3/7 обновить и приложение,
и загрузчик: старый загрузчик не перейдёт на новый адрес после reset сам.
В SETCAN выбрать «Прошивка → CAN / ProtoCAN Boot → Устройство PERIPH»
и нужное назначение. Не загружать поверх загрузчика старый application OUT с
секцией codestart во Flash.
4. После reset пустая EEPROM или старая разметка автоматически ведут в CAN recovery.
Передать новое приложение через ProtoCAN Boot, дождаться пробного запуска и
проверить MEMORY_INFO page 2: pending=FF, active=A. Затем проверить обновление в B.
Старая SPI-ROM разметка с AA08 по адресу 0 несовместима с новым журналом.
Первое обновление заменяет её; параметры по прежнему адресу сохраняются.
Загрузчик не выполняет скрытую миграцию и не меняет boot pins программно.
## Проверки и границы проверенного
`python c/protocan-boot/tests/run_tests.py` (переменная CC — clang/gcc) проверяет
ядро, приложение/загрузчик, wide-octet режим, журнал, обрыв публикации на каждом
из 69 возможных положений, пробный запуск, CONFIRM, откат, SCI8 и границы памяти.
Python-тесты проверяют клиентские запросы, паспорт, фильтрацию ответов и лимит A/B.
Проверка синтаксиса использует настоящие DSP2833x headers. Импорт и сборка TI/CCS,
раскладка MAP и реальные COFF LOAD-адреса проверены; физические CAN/SPI/reset
на плате требуют стендовой проверки. Отдельные проекты и команды сборки описаны
в [инструкции CCS](../../projects/README.md).
CRC32 защищает от повреждения, криптографической подписи и anti-rollback по
версии в этом порту нет. Удалённый CONFIRM подтверждает готовность приложения,
но не заменяет проверку датчиков/силовой части на стенде.
Аппаратный формат SPI boot описан в [TI Boot ROM Reference Guide](https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/171/2742.Boot-ROM.pdf).
В A/B-схеме ROM выбирает Flash, а разбор EEPROM выполняет этот загрузчик.
Проект предоставляет `f28335_can_application_config.h` в include paths.
Он задаёт `F28335_CAN_BOOT_APPLICATION_ENABLED` (0/1) и при включённом модуле
`F28335_CAN_BOOT_FIRMWARE_VERSION` из версии приложения. В 167 это ручной
`firmware_version.h`; профиль включён только при M95M02 без `FLASH_BOOT`.
Локальный `Source/Internal/can_boot.c` содержит только `F28335Boot_Quiesce`
со штатной остановкой нагрузки. Общие `.c` повторно включать в него не нужно:
они компилируются единственным linked resource общей библиотеки.
Постоянный Flash-загрузчик по-прежнему собирается отдельным проектом
`projects/ccs/f28335` и не линкуется в RAM-приложение.