Баузбенд FM100B: - найден прозрачный мост ПК<->модуль (включение с зажатой МЕНЮ), проверен живьём - расшифрована контрольная сумма кадров (one's complement, BE), сверена с ответом рации - инструмент tools/fm100b.py (ping/send/raw/scan) - cmd 0x25 = запрос версии, модуль отвечает V1.2.0.32 (совпало с офиц. образом) - разобран диспетчер входящих кадров: 193 записи, реальный код у 10 команд - cmd 0x59 = индикация приёма, она же управляет гейтом звука PA14 - исправлено: boot-handshake это cmd 0x84, а не 0x64 (research/re/dmr.md) Спектроанализатор REFV DualTachyon (docs/refw-spectrum.md): - вызывается как функция горячей клавиши №22 Analog Spectrum - вход 0x08009CAA -> обычный 0x080139E4 / по зоне 0x08015318 - спектр это экран №11; тик 0x08013BA4 (автомат на 4 состояния), клавиши 0x08013BFC Декомпозиция (docs/firmware-parts.md): - два процессора + внешний SPI = три канала внедрения - карта ресурсов SPI: шрифты, пиньинь, голос, таблица Unicode - найден штатный загрузчик ресурсов FontVoicePicture (шрифты/голос/картинки) - дерево меню целиком: MIC/SPK Gain, RX/TX Limit, SMS Format уже в стоке - аудио двухступенчатое: PA2 питание УНЧ, PA14 гейт от DMR-модуля Прочее: - везде исправлен режим прошивки: тангента PTT вместо клавиши "*" - устаревший Ru-4D_Flasher.exe удалён из репозитория - добавлены инструменты реверса: xref, refs, gpiomap, gpioscan, schem
8.2 KiB
Спектроанализатор REFV (DualTachyon) — где он лежит
Разбор по образу refw/rt-4d-refw-beta42.bin
(251 904 Б, md5 c6ab8306b5512b21b1f49fda8df2b1f5, база загрузки 0x08002800).
Именно эту реализацию хвалят пользователи. Ниже — как до неё добраться и из чего она состоит.
1. Как спектр вызывается
Спектр не является пунктом меню. Это функция назначаемой клавиши № 22 —
Analog Spectrum в списке функций горячих клавиш (0x080213A9, записи по 16 байт).
В стоке та же функция есть под номером 21 — REFV сдвинул нумерацию, вставив
Bandwidth Toggleна позицию 15.
Диспетчер функций клавиш: TBH @0x080094EC, 45 ветвей (cmp #44 перед таблицей),
таблица с 0x080094F0. Ветка 22 → 0x08009CAA.
2. Точка входа 0x08009CAA
if (mode == 3 || mode == 4) return; // в этих режимах спектр запрещён
bl 0x08010ADC; // подготовка
// [area*5 + 0x84] — режим области:
// 0=Frequency, 1=Channel, 2=Zone
if (area_mode == 2) bl 0x08015318; // ← спектр ПО ЗОНЕ
else bl 0x080139E4; // ← ОБЫЧНЫЙ спектр
goto 0x08009BC0; // общий выход
Это ровно совпадает с официальным описанием REFV: «переключитесь в режим VFO или канала, если нужен обычный спектр; из зоны он сканирует эту зону».
3. Обычный спектр — 0x080139E4 (инициализация)
0x080139E4 push {r4-r8,lr}
0x080139E8 bl 0x08014888 ; подготовка подсистемы
... ; сброс флагов состояния
0x08013A2C mla r2, #0x30, chan, r3 ; запись канала = 48 байт
0x08013A30 ldr [r2+5] -> [r4+5] ; копирование частоты RX/TX
0x08013A38 ldr [r2+9] -> [r4+9] ; в рабочий VFO
... ; полоса/режим: bfi в [r4], [r4+4], [r4+0xe]
0x08013A86 bl 0x08011164 ; применить настройки ВЧ-тракта
0x08013AA6 bl 0x080136EC ; подготовка экрана
0x08013ABA bl 0x08013944 ; отрисовка шапки
0x08013AC8 bl 0x08015978 ; печать числа (r1=2 разряда)
0x08013AF8 ite eq / 'W' : 'N' ; метка полосы Wide/Narrow
0x08013B1C bl 0x0801C62C ; запуск
0x08013B22 movs r2,#0x0B
0x08013B24 strb r2,[0x200009B0] ; ← ЭКРАН = 11
0x08013B26 pop
Ключевой вывод: спектр — это экран № 11. Архитектура та же, что в стоке
(g_screen, значения 0…11), только переменная в REFV живёт по адресу 0x200009B0.
4. Модуль спектра целиком
| Адрес | Роль |
|---|---|
0x08009CAA |
точка входа с горячей клавиши, выбор обычный/зонный |
0x080139E4 |
инициализация обычного спектра, ставит экран = 11 |
0x08013BA4 |
тик: автомат на 4 состояния, счётчик [база+0x3E] & 3 |
0x08013BFC |
обработчик клавиш спектра, cmp r0,#0x10 + TBH @0x08013C20 (17 клавиш) |
0x08013598 |
шаг развёртки (состояние 1) |
0x08012FA0 |
рабочий обработчик (состояния 2 и 3) |
0x0801307C |
ветка при состояние > 1 |
0x080135E8 |
помощник (вызывается из 0x0801449C) |
0x080136EC, 0x08013944, 0x08015978 |
подготовка экрана, шапка, печать чисел |
0x08014888 |
инициализация подсистемы |
0x08015318 |
спектр по зоне — отдельная реализация |
Автомат тика 0x08013BA4
state = (state + 1) & 3; // [база+0x3E]
switch (state) {
case 1: flags[1]=flags[2]=0; bl 0x08013598; break; // шаг развёртки
case 2: flag=0; goto 0x08012FA0; // обработка
case 3: flag=1; goto 0x08012FA0;
default: goto 0x0800A57C; // пометить перерисовку
}
Развёртка размазана по тикам главного цикла — экран не блокируется, поэтому спектр и ощущается отзывчивым.
Спектр по зоне 0x08015318
Перебирает 200 каналов зоны (cmp r6,#0xC8), запись зоны — 0x1BD байт:
for (i = 0; i < 200; i++) {
ch = zone[i].channel; // halfword, отбрасывается если >= 0x400
if (!(zone.scanlist_bitmap[i>>3] >> (i&7) & 1)) continue; // битовая карта scan-list
read_channel(sp, 0x30*ch + 0x4000); // запись канала 48 байт из SPI
// разбор полей: частота ubfx(…,8,12), CTCSS, полоса, режим
// укладка в массив с шагом 28 байт
}
Отсюда и фича «зонный спектр показывает живую информацию о субтонах».
5. Прочие детали
- Перерисовка:
0x0800A5FC—TBBна 12 экранов (cmp #0x0B), каждая ветка делаетmemset(флаги_экрана, 1, N). Для экрана 11 — 16 элементов по адресу0x200000A9. - Идиом связки экранов встречается в 6 местах:
if (screen == 11 || (prev == 11 && (screen & ~4) == 8))— экраны 8 и 12 накладываются поверх спектра (меню/подсказки).
6. Что даёт REFV сверх стока (полная таблица UI, 338 записей)
Новые функции горячих клавиш: Bandwidth Toggle, Talker Alias, RX AM/FM/**SSB** SW,
DMR DCDM Switch, DMR TS/CC Switch, DMR Key Select, Next Zone, DTMF List,
Freq Monitor, Last Call Info, Address Book, Contacts List.
Новое в меню: верхнеуровневое Extra, Extra hotkey + 0…9 Hotkey,
Edit Scan List в зонах, SMS Templates, Time Calibrate, AM/FM/SSB RX в канале,
Last Channel, Skip Scan, Radio Info, Flash Type.
7. Как это перенести к нам
Прямой перенос бинарного кода невозможен — REFV написан с нуля, у него своя карта
памяти и свои структуры (запись канала 48 Б, запись зоны 0x1BD Б, экран в 0x200009B0).
Переносится архитектура:
- Спектр — отдельный экран в общей диспетчеризации, а не модальный цикл.
- Развёртка разбита на состояния по тикам, поэтому UI не подвисает.
- Вход — функция горячей клавиши, а не пункт меню.
- Отрисовка перерисовывает только помеченные элементы (массив флагов).
В нашей прошивке всё это ложится на уже найденные точки: хук 0x080207E6 (отрисовка) и
0x08020816 (клавиши) в ui_tick_normal @0x080207DC, диспетчеризация по
g_screen @0x200008B3. Обязательно вызывая оригинальный обработчик — см.
docs/firmware-parts.md.