F28335 + M95M02: CAN, отдельный загрузчик и A/B
Реализация состоит из Flash-загрузчика periph_167/Bootloader, переносимого
f28335_boot_store.c, аппаратного f28335_boot_hw.c и адаптера
f28335_can_boot.c. Приложение подключает их через Source/Internal/can_boot.c.
В сборке EEPROM_M95M02=0 CAN Boot отключён. Для установленной M95M02 — значение 1.
Адрес и формат
Device Type 3, Device ID 7, имя F28335-M95M02, Product 0x2833, HW 1.
В приложении FW берётся из firmware_version.h, формат major<<24 | minor<<16 | patch;
для версии 1.1.2 это 0x01010002. Загрузчик сообщает версию подтверждённого образа
из журнала, при отсутствии такого образа — 0. Версия кандидата передаётся в BEGIN_COMPAT.
CAN 250000 бит/с, Extended ID, окно 16 блоков по 8 октетов.
ENTER_BOOT для session=1: 0x13790102, STATUS: 0x1B7C0102.
Образ — 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. После ошибки публикации журнал перечитывается;
ошибка чтения блокирует последующие записи.
Сценарий обновления и отката
- Приложение принимает ENTER_BOOT, останавливает управление нагрузкой, выставляет 4 мА и выдерживает секундный STOP, затем сохраняет session в NOINIT RAM 0x50..0x57. Watchdog выполняет reset. ACK ENTER_BOOT отправляет уже Flash-загрузчик; приложение ничего не стирает.
- BEGIN_IMAGE/BEGIN_COMPAT проверяют размер, Product, HW и сессию. Неактивный слот выбирается автоматически; при первом образе это A. ERASE инвалидирует только его manifest. Полного стирания EEPROM не требуется.
- Последовательные DATA_A/B записываются с немедленным readback. VERIFY
проверяет потоковый CRC32, CRC32 EEPROM и полную таблицу SCI8.
Разрешена загрузка только в CPU word RAM
[0x8000,0xE000): максимум 64 секции, без пересечений, усечений и хвостовых данных; entry должен попасть в секцию. Запись в Flash, периферию, стек, RAM загрузчика и handoff запрещена. - COMMIT повторно проверяет образ и публикует pending в журнале. Подтверждённый слот сохраняется. Повтор COMMIT безопасен. REBOOT выполняется после физического CAN ACK ответа. Потеря ACK/тайм-аут передачи отменяет запрос reset.
- Перед первым запуском кандидата загрузчик сохраняет attempted=1, затем проверяет и копирует SCI8 в RAM. Следующий reset без CONFIRM сбрасывает pending и запускает прежний active. Если прежнего образа нет — остаётся CAN recovery.
- Новое приложение включает 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 остаётся heartbeat. 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.
Первичная установка
- Собрать приложение с EEPROM_M95M02=1 и обновлённым F28335.cmd; получить SCI8 BIN. Старые BIN/OUT автоматически не заменены. Приложение должно содержать интеграцию READY/CONFIRM, иначе на следующем reset оно останется неподтверждённым кандидатом.
- Собрать отдельный загрузчик TI C2000 COFF compiler:
Bootloader/build.ps1 -CompilerRoot <путь-к-ti-cgt-c2000>. Результат —Bootloader/build/F28335_CAN_AB.outи MAP. - Один раз установить этот OUT через JTAG и выбрать аппаратный Flash boot согласно схеме платы. Не загружать поверх него старый application OUT с секцией codestart во Flash.
- После 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 и физические CAN/SPI/reset на плате ещё не подтверждены.
CRC32 защищает от повреждения, криптографической подписи и anti-rollback по версии в этом порту нет. Удалённый CONFIRM подтверждает готовность приложения, но не заменяет проверку датчиков/силовой части на стенде.
Аппаратный формат SPI boot описан в TI Boot ROM Reference Guide. В A/B-схеме ROM выбирает Flash, а разбор EEPROM выполняет этот загрузчик.