Open Stream Deck

Загрузчик

Как устройство входит в загрузчик производителя, протокол записи и перезапуск приложения.

Прошивка записывается через штатный загрузчик производителя. Он занимает flash 0x08000000..0x08003FFF, в образ приложения не входит и обновлением не затрагивается. Запись идёт только в область приложения 0x08004000..0x0801B8EF, то есть 96 496 байт.

Прошивальщик находится в src-tauri/src/firmware.rs приложения.

Вход в загрузчик

Состояние устройстваСпособ входа
Open Stream DeckКоманда OSD1 0A BOOT с сигнатурой OSDBOOT!. Поддержка объявляется битом 0 байта 17 в Feature report 3
Штатная прошивка AJAZZ (0300:1020)Output report 512 байт: CRT, два нулевых байта, APPNEW
Замкнуты два контакта на плате при подключении USBЗагрузчик остаётся сам

Программные команды делают одно и то же. Через ROM-функции flash переписывается служебный сектор 0x0807E000: слова 0 и 2 сохраняются, слова 1 и 3 инвертируются, по адресу 0x0807E010 записывается маркер 0x21436587. После этого выполняется сброс через регистр 0x40002000.

Загрузчик остаётся в режиме прошивки, если выполнено любое из условий:

  • замкнут контакт (0x4001D000, бит 0);
  • по 0x0807E010 лежит маркер 0x21436587;
  • в RAM по адресу 0x20028000 лежат слова 0x32021688 и 0x19714568, которые загрузчик стирает при старте;
  • вектор сброса приложения равен 0xFFFFFFFF.

Протокол загрузчика

Загрузчик работает как HID EEEF:2929. Отчёты по 64 байта без Report ID. На каждую команду загрузчик отвечает 64 байтами и повторяет код команды в байте 3.

КодБайты 0..2Байт 3ДалееДействие
D20D2смещение u32, размер в байтах u32Стирание области блоками по 512 байт
D1смещение, 24 битаD160 байт данныхЗапись 15 слов, хвост дополняется FF
D30D3число слов u32, CRC u32Проверка CRC-16/ARC по записанному образу
AA0AA02Переход в приложение без ответа

После успешной D3 загрузчик записывает в сектор 0x0807E000 значение CRC, его инверсию, число слов и его инверсию, затем стирает маркер.

Перезапуск

По команде AA загрузчик сразу переходит к вектору сброса приложения, без сброса чипа.

  • Вход контактами делается при включении питания, поэтому приложение стартует само.
  • Вход программной командой требует переподключения USB. Ни эта прошивка, ни штатная не стартуют после прыжка без него.

Тёплый старт

Watchdog по адресу 0x40005000 переживает программный сброс. Загрузчик его не включает, но кормит. Поэтому прошивка кормит watchdog с первой инструкции Reset_Handler и во время настройки тактирования.

Служебная область flash 0x082000xx читается только после включения питания. После тёплого сброса её чтение приводит к отказу. platform_init читает адреса 0x082000A4 и 0x082000C8 через пробу: обработчик отказа пропускает инструкцию, а значения берутся из кэша в секции .noinit, которая переживает тёплый сброс, либо из запасных констант.