Обеспечь единый процесс обновления для STM32F103/F407/G474 и TMS320F2812/F28335: discovery, служебные ответы, BUSY, тайм-аут сессии и подтверждение приложения. Добавь самостоятельные проекты CCS, аппаратные хранилища и Python-клиент. Совместимость: структуры конфигурации и порта расширены, поэтому потребители должны пересобраться и обнулить новые поля. Для C28x callbacks используют pcan_boot_byte_t; периодический pcan_boot_poll обслуживает discovery и настроенный тайм-аут.
19 KiB
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. После ошибки публикации журнал перечитывается;
ошибка чтения блокирует последующие записи.
Сценарий обновления и отката
- Приложение принимает 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 загрузчик не использует. 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:
python c/protocan-boot/projects/build.py --device f28335 --compiler <путь-к-ti-cgt-c2000>. Результат —projects/ccs/f28335/Debug/F28335_CAN_AB.outи MAP. - Установить обновлённый OUT через JTAG и выбрать аппаратный Flash boot согласно схеме платы. При переходе с общего адреса 3/7 обновить и приложение, и загрузчик: старый загрузчик не перейдёт на новый адрес после reset сам. В SETCAN выбрать «Прошивка → CAN / ProtoCAN Boot → Устройство PERIPH» и нужное назначение. Не загружать поверх загрузчика старый 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 и реальные COFF LOAD-адреса проверены; физические CAN/SPI/reset
на плате требуют стендовой проверки. Отдельные проекты и команды сборки описаны
в инструкции CCS.
CRC32 защищает от повреждения, криптографической подписи и anti-rollback по версии в этом порту нет. Удалённый CONFIRM подтверждает готовность приложения, но не заменяет проверку датчиков/силовой части на стенде.
Аппаратный формат SPI boot описан в TI Boot ROM Reference Guide. В 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-приложение.