- README §12.8: таблица gate (PER0 3/5/14, PER2 1-11 при FBGAIN -80..0, доставка STATUS 0% при <=-40, плато ~50% при -20..0), вердикт - NOTES §2.2: разбор плато 50% (структурное: fb-RX платы A глохнет в её же TX-бёрсты, duty 57% при -p 4000), окно fb-TX -20..-10, пересмотр критерия доставки (STATUS кумулятивен, 5 Гц эффективных достаточно), TDD не нужен - BENCHMARK.md: framegen 570.6 мкс/кадр 255 Б -> STATUS 10 Гц ~0.6% ядра
13 KiB
NOTES.md — грабли, ограничения и почему так
Здесь собрано всё, что не является кодом, но экономит дни отладки.
1. Плата: Pluto+ ≠ ADALM-Pluto
Наши платы — клоны «Pluto+» (Zynq-7020). Отличия от стокового ADALM-Pluto (7010), которые влияют на проект:
| Pluto+ (у нас) | ADALM-Pluto сток | |
|---|---|---|
| SoC | Zynq-7020 | Zynq-7010 |
| Ядра ARM | 2 активных | 1 (второе — через хак) |
| RAM | 1 ГБ | 512 МБ |
| Ethernet | есть гигабитный | нет (только USB) |
Следствия: бюджет «одно ядро на DSP, второе на IO» валиден только на наших платах; на стоковом Pluto весь тракт не поместится. Все замеры (docs/BENCHMARK.md) сделаны на Pluto+.
Особенности прошивки v0.38:
- нет sftp-server → только
scp -O(legacy protocol); - rootfs в RAM → всё в /tmp и /root пропадает при ребуте; бинарники
заливаются заново (
make deploy), «установить навсегда» = пересборка прошивки, нам не нужно; - BogoMIPS 333 в /proc/cpuinfo — артефакт таймера, реальная частота 667 МГц;
- пароль root:
analog.
2. FDD и самоглушение (главный риск этапа «в воздух»)
План FDD: A TX 915 / RX 868; B TX 868 / RX 915 (разнос 47 МГц). Проблема: дуплексеров нет. Собственный передатчик платы в паре сантиметров от собственного приёмника:
- широкополосный шум TX попадает в полосу RX даже при разносе 47 МГц;
- сильный сигнал TX блокирует (десенсибилизирует) входной каскад RX.
Характерный симптом: симплекс и loopback работают идеально, а в дуплексе RX платы «глохнет», как только её TX активен. Это не баг кода.
Меры (по нарастанию):
- максимальный
tx_attenuation, какой позволяет линия; - физический разнос TX/RX антенн + кросс-поляризация;
- SAW-фильтр 868 МГц на RX-вход (копеечный, SRD-диапазон);
- если ничего не помогает — честный TDD на одной частоте.
Поэтому порядок работ: сначала симплекс (обе платы 915 МГц, полудуплекс по очереди), FDD — отдельным этапом с замерами деградации RX при активном TX.
2.1. Предварительные замеры (этап 1, §10 п.7 — FDD-водопровод)
Числа сняты на сконфигурированном, но молчащем обратном тракте (LO 868
поднят, hardwaregain выставлен, но DMA обратного TX ничего не пушит).
Полноценный gate с реальным STATUS-трафиком — этап 2, числа уйдут в §2.2.
- Самоглушения от «просто включённого» обратного тракта не видно. Форвард
A→B под FDD (1 МБ,
-p 4000, group-FEC) байт-в-байт и при fb-TX-g -89(≈выкл), и при-g -20(штатное). Активный обратный LO 868 в 47 МГц от RX 915 приёмник данных не глушит — на кабеле+аттенюаторе. Это ответ на вопрос PER₁ (десенс от включённого тракта), но НЕ на PER₂ (десенс от реального излучения STATUS) — тот снимается в этапе 2. - Диагностика: пустой файл на выходе RX ≠ самоглушение. Симптом «0 кадров,
RSSI −100» — это НЕ глушение, а мёртвый вход: остаточный процесс держит
RX-DMA (
cf-ad9361-lpc) от неубитого прошлого запуска. Глушение выглядит ИНАЧЕ — сильный RSSI (−48) при разрушенном EVM (−2.5). Различать по RSSI. Лечение:killall -9 receiver transmitterперед каждым стартом (уже вscripts/test_fdd_fwd.sh). - Ридбэк LO округляется PLL. AD9361 — дробный-N синтезатор с шагом ~2 Гц:
868000000читается как867999998. Это норма, не ошибка; сверка ридбэка идёт с допускомFDD_LO_TOL_HZ=100 Гц (common.c). - Канал деградировал против этапа 0. Эталон регрессии сдвинут
-p 3000→-p 4000(на 3000/3500 теперь Overrun+потери). Направление B→A флапает даже на-p 4000при СИЛЬНОМ RSSI (−33…−35) — вероятна компрессия входа RX (усиление 50 дБ избыточно). Проверить снижением RX/TX gain до свипа частот.
2.2. Gate-замер самоглушения (этап 2, 2026-07-16) — вердикт: FDD принят
Условия: кабель+аттенюатор, данные A→B 915 (TXGAIN −30, -p 4000,
GROUPFEC=0 — сырой PER без маскировки), STATUS B→A 868 (10 Гц),
1 МБ = 1024 кадра на прогон. Полные числа — README §12.8.
- PER₀ (симплекс, 3×): потерь 3/5/14 → 0.29–1.37%, среднее 0.72% (канал флапает, см. выше).
- PER₂ (FDD, STATUS в эфире, FBGAIN −80…0, 8 прогонов): потерь 1–11, среднее 0.51%. PER₂−PER₀ ≈ −0.2 п.п. — излучение STATUS форвард-линк не трогает вообще, ни при каком усилении. PER₁≈PER₀ снят ранее (§2.1).
- Доставка STATUS B→A: 0% при FBGAIN ≤ −40 (не пробивает аттенюатор); плато ~50% при −20…0 (47/52/52/50/51%) — от усиления НЕ зависит.
- FBGAIN=0 дал первые «RS битых: 3» на RX данных платы B → лёгкий самодесенс B на максимуме fb-TX. Рабочее окно fb-TX на кабеле: −20…−10.
Плато 50% — структурное, не RF. Гипотеза: fb-RX платы A десенсится её же
TX-бёрстом (механизм §2, но на стороне A). Duty данных при -p 4000 = 57%
(кадр 5.33 мс + пауза 4 мс); STATUS ~1.4 мс выживает только попав в паузу —
доля доставки ≈ доле тихого времени и потому не зависит от FBGAIN. Проверка
при случае: PAUSE=8000 должен поднять доставку. Приятное следствие: в фазе
ретрансмитов и END-хендшейка ARQ плата A передаёт мало → доставка растёт
именно там, где обратная связь критична.
Вердикт gate. Исходный критерий «≥99% доставки» был перестрахован и пересмотрен: STATUS кумулятивен по построению (потеря безвредна — следующий несёт то же состояние), 50% доставки = эффективные ~5 Гц фидбэка, для ARQ с rate-limit 2× периода и TX-окном ~19 с этого с большим запасом достаточно. Рабочий критерий: доставка стабильна (≥30%) И PER₂−PER₀ ≤ +0.3 п.п. И PER₁≈PER₀ — выполнен, этап 5 (fallback TDD, цена ~8% throughput) не нужен.
Замечание к методике: у приёмника НЕТ флага усиления RX данных (константа
RX_GAIN=50 в коде; -g приёмника — усиление fb-TX). Переменная окружения
RX_GAIN скриптами не читается — прогоны «RX_GAIN=40/30/20» были репликами
FBGAIN=0 (они и дали три точки плато). Гипотеза компрессии входа при RSSI
−33…−35 (см. §2.1) остаётся непроверенной, но gate она не блокирует.
3. Регуляторика (868/915 МГц в регионе ETSI)
- 868 МГц — SRD-диапазон: ограничения на полосу канала (сотни кГц), ЭИИМ и duty cycle. Наш сигнал 1.5 МГц в них не вписывается.
- 915 МГц — в Европе это uplink GSM-900, не ISM (ISM 902–928 — регион США).
Практический вывод: разработка и демо — кабель с аттенюатором или антенны на столе с минимальной мощностью (TX gain от −40) и без внешних усилителей. Это ограничение прототипа фиксируется в отчёте проекта; у целевой системы по ТЗ предполагается лицензированный канал.
4. RF-безопасность
- Кабельный тест только через аттенюатор 30–40 дБ +
-g -40. Прямое соединение TX→RX выжигает входной каскад AD9361. - Диапазон DAC/ADC — 12 бит (±2047 в int16). Клиппинг при амплитуде TX > ~0.5 виден как рост EVM на RX.
5. Особенности liquid-dsp, найденные в бою
- Заголовок пользователя по умолчанию 8 байт. Наш формат — 12 байт.
Без
ofdmflexframegen_set_header_len(fg,12)/ofdmflexframesync_set_header_len(fs,12)байты 8–11 (nblocks, last_block_bytes) в эфир не уходят, RX читает мусор за границей буфера. fec_decode()не сообщает об ошибках: RS-декодер liquid всегда «успешен», неисправимый блок просто отдаёт мусор. Единственный надёжный критерий целостности — CRC/md5 поверх декодированных данных.- Без FFTW liquid молча деградирует на встроенный FFT. Проверка после
сборки обязательна:
grep HAVE_LIBFFTW3F config.log. ofdmflexframesyncсам оценивает и компенсирует CFO по преамбуле; внешний NCO-контур поверх него (как в раннем receiver.c) не нужен и сset_phase(0)на границах буферов — вреден.
6. Почему архитектурные решения именно такие
- Статическая линковка: независимость от libc прошивки, деплой одним файлом, нет возни с sysroot ADI. Цена ~2 МБ — ничто при 1 ГБ RAM.
- rate 1.92, а не 3.84 MSPS: замер (BENCHMARK.md) — 2.34 Msps потолок синхронизатора на кадрах. 3.84 даёт отказ «работает на демо, падает под нагрузкой» — худший для радиолинии вид отказа.
- OFDM оставлен, несмотря на цену CPU: код написан и проверен; single-carrier QPSK дал бы ту же полезную скорость дешевле, но потребовал бы написать и отладить синхронизацию заново. Решение можно пересмотреть, если понадобится rate > 1.92 MSPS (см. резервы в BENCHMARK.md).
- Симплекс раньше FDD: изолирует проблемы кода от проблем RF (п. 2).
7. Быстрые команды-шпаргалки
# что видит плата
iio_info -u ip:192.168.2.1 | less
iio_attr -u ip:192.168.2.1 -c ad9361-phy altvoltage1 frequency # TX LO
# загрузка CPU на плате во время линии (busybox top)
ssh root@192.168.2.1 top
# логи TX/RX после test_file_link.sh
ssh root@<ip> 'cat /tmp/tx.log /tmp/rx.log'