Files
templates/c/protocan-boot/ports/tms320f28335

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. После ошибки публикации журнал перечитывается; ошибка чтения блокирует последующие записи.

Сценарий обновления и отката

  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 остаётся 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.

Первичная установка

  1. Собрать приложение с EEPROM_M95M02=1 и обновлённым F28335.cmd; получить SCI8 BIN. Старые BIN/OUT автоматически не заменены. Приложение должно содержать интеграцию READY/CONFIRM, иначе на следующем reset оно останется неподтверждённым кандидатом.
  2. Собрать отдельный загрузчик TI C2000 COFF compiler: Bootloader/build.ps1 -CompilerRoot <путь-к-ti-cgt-c2000>. Результат — Bootloader/build/F28335_CAN_AB.out и MAP.
  3. Один раз установить этот OUT через JTAG и выбрать аппаратный Flash boot согласно схеме платы. Не загружать поверх него старый 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 и физические CAN/SPI/reset на плате ещё не подтверждены.

CRC32 защищает от повреждения, криптографической подписи и anti-rollback по версии в этом порту нет. Удалённый CONFIRM подтверждает готовность приложения, но не заменяет проверку датчиков/силовой части на стенде.

Аппаратный формат SPI boot описан в TI Boot ROM Reference Guide. В A/B-схеме ROM выбирает Flash, а разбор EEPROM выполняет этот загрузчик.