Maxim d4b5c3f22e docs: разбивка стоимости RX по стадиям — диагноз TX-паузы
Замеры расширенным ofdm_bench (плата B, ядро 0) документированы в
BENCHMARK.md, диагноз — в README §12.5:
- sync-only на сплошных кадрах 1.65 Msps < 1.92 → -p 0 недостижим;
  «запас 1.22×» был артефактом duty 0.571
- конвертация ~бесплатна (85 Msps) → двухпоточный вынос дал ~2%
- RS-декод 275 мкс/блок = 26% эфира кадра (было «мало» — опровергнуто)
- контеншн L2/DDR 0.2% (гипотеза кэша отвергнута)
Вывод: узкое место sync+RS на ядре 0; фикс — вынос RS на ядро 1
(3-стадия), p_min ~3.4→~1.3 мс. Исправлены устаревшие выводы §2 и
рычаг 2 в §12.3. PHY не менялся.
2026-07-14 14:05:46 +03:00
2026-07-14 11:49:12 +03:00
2026-07-10 16:25:29 +03:00

pluto-link — OFDM-радиолиния между двумя PlutoSDR (весь код на ARM внутри Pluto)

Цифровая радиолиния точка-точка на базе двух ADALM-Pluto+ (клон, Zynq-7020). PHY: OFDM (liquid-dsp) + RS(255,223) FEC. Весь сигнальный тракт исполняется на ARM Cortex-A9 внутри Pluto; хост-ПК нужен только для сборки, заливки бинарей и снятия логов. Прототип в рамках ОКР «R-Link» (двухранговая самоорганизующаяся сеть); данный репозиторий покрывает уровень PHY/линка.


1. Аппаратная платформа (фактическая, проверено)

Параметр Значение Как проверено
Плата Pluto+ (клон, Zynq-7020, AD9361) cat /proc/cpuinfo — 2 ядра
CPU 2 × Cortex-A9 @ 667 МГц, NEON Features: ... neon vfpv3
RAM 1 ГБ (доступно ~1000 МБ) free
Прошивка v0.38-4-g95aad-dirty баннер SSH
Доступ SSH root@192.168.2.1 (пароль analog), USB-Ethernet

⚠️ Стоковый ADALM-Pluto (7010, 512 МБ, 1 ядро) — другая плата; все бюджеты CPU в этом документе рассчитаны для Pluto+. Не путать.

⚠️ В прошивке v0.38 нет sftp-server → заливать файлы только scp -O (legacy-протокол).

2. Бюджет CPU — главное ограничение проекта

Замерено офлайн-бенчмарком src/ofdm_bench.c прямо на ARM Pluto (одно ядро, static, -O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -ffast-math, liquid-dsp 1.8.0 с FFTW/NEON — проверено по HAVE_LIBFFTW3F в config.log):

Режим ofdmflexframesync Пропускная способность Вывод
Поиск преамбулы (шум) 5.32 Msps дежурный режим, не лимитирует
Приём кадров (duty ~57%) 2.34 Msps узкое место

Следствия (зафиксированы как проектные решения):

  • Рабочий sample rate = 1.92 MSPS. Запас 1.22× на ядре синхронизатора; второе ядро — под IIO, RS-декод, ввод-вывод.
  • 3.84 MSPS запрещён: система работает на редких пакетах и лавинообразно разваливается под нагрузкой (0.61× от realtime). Это худший вид отказа — «на демо работало».
  • Полезная скорость ≈ 1.31.5 Мбит/с (~160190 КБ/с). Файл 10 МБ ≈ 1 мин.
  • Параметры замера: M=64, CP=16, taper=4, QPSK, CRC32, payload 1275 Б. Полный протокол — docs/BENCHMARK.md. При любом изменении PHY-параметров бенчмарк перегоняется до изменения кода тракта.

3. Структура репозитория

pluto-link/
├── README.md                  # этот файл
├── CLAUDE.md                  # краткие правила для Claude Code
├── makefile                   # цели: all, tx, rx, bench, deploy, clean
├── toolchain.env              # CROSS=arm-linux-gnueabihf-, SYSROOT=$HOME/xarm
├── src/
│   ├── common.h               # параметры OFDM/RS, дефолты, прототипы
│   ├── common.c               # pluto_init (local:), pluto_configure
│   ├── transmitter.c          # stdin → OFDM → AD9361 TX
│   ├── receiver.c             # AD9361 RX → OFDM sync → stdout
│   └── ofdm_bench.c           # бенчмарк CPU (не удалять!)
├── scripts/
│   ├── build_deps.sh          # кросс-сборка FFTW + liquid-dsp → $HOME/xarm
│   ├── deploy.sh              # scp -O бинарей в /tmp обеих плат
│   └── test_file_link.sh      # e2e: файл → эфир → md5-сверка
└── docs/
    ├── BENCHMARK.md           # методика и результаты замеров CPU
    └── NOTES.md               # FDD, регуляторика, известные грабли

4. Среда разработки и сборка

4.1 Хост

Любой Linux; проверено на Raspberry Pi OS 64-bit (aarch64). Кросс-тулчейн:

sudo apt install -y build-essential autoconf automake libtool git wget \
                    gcc-arm-linux-gnueabihf

4.2 Зависимости (один раз, ~20 мин)

scripts/build_deps.sh собирает в $HOME/xarm статические armhf-библиотеки. Порядок важен: liquid зависит от FFTW и libfec, поэтому они собираются до него.

  1. FFTW 3.3.10: --enable-single --enable-neon --enable-static
  2. libfec (jgaeddert): Reed-Solomon для liquid. liquid не реализует RS сам — оборачивает libfec. Без неё fec_create(LIQUID_FEC_RS_M8) вернёт NULL и -c rs8 молча пойдёт БЕЗ FEC. Собирать строго ДО liquid.
  3. liquid-dsp 1.8.0: с CPPFLAGS=-I$HOME/xarm/include LDFLAGS=-L$HOME/xarm/lib и обходом autoconf-кросс-проблемы: ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes
  4. libiio v0.25: только local backend (network/usb/xml/iiod отключены).
  5. libad9361-iio: FIR-фильтр для sample rate < 2.083 MSPS (ad9361_set_bb_rate). Без него AD9361 отвергает 1.92 MSPS (EINVAL).

После сборки liquid обязательно проверить, что подхвачены и FFTW, и libfec: grep -E "HAVE_LIBFFTW3F 1|HAVE_LIBFEC 1" config.logобе строки. Без FFTW liquid молча падает на встроенный FFT (бюджет CPU невалиден); без libfec нет RS.

⚠️ При обновлении зависимостей liquid надо пересобирать через make clean: его makefile не отслеживает зависимость от config.h, и configure+make без очистки лишь переустановят старую libliquid.a (без FEC). Проверка перед деплоем: arm-linux-gnueabihf-nm $XARM/lib/libliquid.a | grep -c init_rs_char → ненулевое = RS-символы libfec действительно связаны.

4.3 Ключевые решения по сборке

  • Только статическая линковка (-static). Причина: не зависим от libc прошивки Pluto, не таскаем .so, деплой = один файл. Цена +2 МБ — ничто при 1 ГБ RAM.
  • Флаги обязательны: -O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -ffast-math. Без NEON бюджет CPU из раздела 2 не выполняется.
  • Одной командой:
arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard \
  -ffast-math -static src/receiver.c src/common.c -o receiver \
  -I$HOME/xarm/include -L$HOME/xarm/lib \
  -lad9361 -liio -lliquid -lfec -lfftw3f -lm

Порядок библиотек критичен при статической линковке: зависимый идёт раньше (-lad9361 перед -liio, -lliquid перед -lfec).

4.4 Деплой

scp -O transmitter receiver root@192.168.2.1:/tmp/   # Pluto A
scp -O transmitter receiver root@<pluto_B>:/tmp/     # Pluto B

rootfs Pluto живёт в RAM: /tmp очищается при ребуте — это нормально, deploy.sh заливает заново.

5. Правила кода (конституция)

  1. Язык — C. Python/GNU Radio в тракте данных запрещены.
  2. Железо — только libiio, контекст local: (код исполняется на Pluto). Сетевые контексты ip: — только для отладочных утилит с хоста.
  3. Бюджет: считай, что у тебя одно ядро 667 МГц на DSP; второе занято IIO/FEC/IO. Любая новая нагрузка в тракте — сначала через ofdm_bench.
  4. Тяжёлые зависимости (FFmpeg, cJSON и т.п.) — запрещены. JSON руками, видео — raw UDP.
  5. Порядок отладки: кабель+аттенюатор → антенны на столе → дистанция. Никогда не отлаживать новый код сразу «в воздухе».
  6. Изменил PHY-параметры (M, CP, модуляция, rate) — перегони бенчмарк и обнови docs/BENCHMARK.md в том же коммите.

6. Параметры радиотракта

Параметр Значение Примечание
Sample rate 1 920 000 см. раздел 2; 3.84 MSPS запрещён
Полоса 1 500 000 ~0.78 × rate
Частота (симплекс-тест) 915 МГц обе платы на одной частоте
FDD (этап 2) A: TX 915/RX 868; B: TX 868/RX 915 разнос 47 МГц
TX gain (кабель) 40 дБ + аттенюатор 3040 дБ обязателен
TX gain (антенны) 20…0 дБ начинать с минимума
RX gain 50 дБ, manual фиксированный
OFDM M=64, CP=16, taper=4, QPSK liquid defaults + CRC32
FEC RS(255,223), payload ≤ 1024 Б 5 блоков на кадр

⚠️ FDD без дуплексеров: собственный TX 915 МГц глушит свой RX 868 МГц широкополосным шумом. Симптом: loopback работает, дуплекс в эфире — нет. Меры: max tx_attenuation, разнос/кросс-поляризация антенн, SAW-фильтр 868 МГц на RX. Подробнее — docs/NOTES.md.

⚠️ Регуляторика: 868 МГц — SRD-диапазон (ограничения полосы/мощности/ duty cycle), 915 МГц в регионе ETSI занят GSM-900 uplink. Работа — кабель или минимальная мощность на столе, без внешних усилителей.

7. Формат кадра

OFDM-кадр liquid: [преамбула][заголовок 12 Б][payload ≤ 1275 Б][CRC32]

Заголовок (12 байт):
 0-1   0xF0 0xAA        сигнатура
 2-5   seq (uint32 BE)  порядковый номер кадра
 6-7   len (uint16 BE)  длина исходных данных до FEC
 8-9   nblocks          число RS-блоков
 10    last_block_bytes хвост последнего блока (0 = полный)
 11    резерв

⚠️ Критично: у liquid заголовок пользователя по умолчанию 8 байт. Байты 811 передаются только после явного вызова на обеих сторонах:

ofdmflexframegen_set_header_len(fg, 12);   // TX
ofdmflexframesync_set_header_len(fs, 12);  // RX

Без этого RX читает hdr[10] за пределами буфера (маскируется обрезкой по original_len, но это мина).

8. Запуск

8.1 Передача файла Pluto→Pluto

scp -O test.bin root@192.168.2.1:/tmp/

# Pluto B — приёмник
ssh root@<pluto_B> '/tmp/receiver -f 915000000 -r 1920000 -b 1500000 -c rs8 \
    > /tmp/out.bin'

# Pluto A — передатчик (кабель: -g -40 + аттенюатор!)
ssh root@192.168.2.1 'cat /tmp/test.bin | /tmp/transmitter -f 915000000 \
    -r 1920000 -b 1500000 -g -40 -p 0 -c rs8'

# сверка
md5sum test.bin && ssh root@<pluto_B> 'md5sum /tmp/out.bin'

8.2 Бенчмарк CPU (перед любым изменением PHY)

scp -O ofdm_bench root@192.168.2.1:/tmp/
ssh root@192.168.2.1 '/tmp/ofdm_bench 1.92'
# критерий: "сигнал+кадры" ≥ 1.2× цели на одном ядре

9. Известные проблемы и техдолг

# Проблема Статус
1 Заголовок 12 Б vs 8 Б по умолчанию у liquid (раздел 7) исправлено: set_header_len(12) на обеих сторонах
2 recovered[4096] в receiver при лимите nblocks≤100 (22 КБ) → переполнение стека на битом заголовке. Лимит должен быть 4096/RS_DATA = 18 исправлено: лимит nblocks ≤ 4096/RS_DATA = 18
3 fec_decode() liquid не сообщает о неисправимых RS-блоках → счётчик rs_saved фиктивен. Достоверный критерий — только CRC/md5 поверх данных исправлено: CRC32 поверх данных до RS на TX, сверка после декода на RX; rs_saved/rs_fail достоверны (подтверждено loopback'ом, §12.2)
4 Внешний NCO-CFO в receiver: set_phase(0) на границах буферов рвёт фазу; ofdmflexframesync и так компенсирует CFO сам исправлено: внешний NCO удалён, CFO оставлен только как телеметрия
5 TX пушит весь буфер 16384 сэмпла при кадре ~10300 → ~35% эфира впустую + паузы -p исправлено: iio_buffer_push_partial(idx) + дренаж хвоста DMA перед закрытием
6 Нет ARQ: потерянный кадр = молчаливая дыра в файле. seq в заголовке есть, но RX его игнорирует ⚙️ частично: добавлен детектор пропусков seq (лог [ПОТЕРЯ] + счётчик «Потери seq»); ARQ ещё нет
7 Файл reciever.c → переименовать в receiver.c (make его ждёт) исправлено

10. Дорожная карта

  1. Бенчмарк CPU на ARM Pluto → выбран rate 1.92 MSPS
  2. Перенос TX/RX на Pluto (local:), фиксы техдолга #1#7 (см. §9)
  3. ⚙️ текущий этап — файл через эфир (OTA). Ввод в строй строго OTA; кабельный этап осознанно пропущен. 2026-07-14: цифровой BIST-loopback подтвердил DSP-тракт (§12.2) 2026-07-14: первый OTA-приём — 10 КБ байт-в-байт, EVM 22.7 дБ (§12.3) 2026-07-14: пауза -p 6000 убрала throughput-потери (100 КБ — 100/100); на 1 МБ остаточный PER ≈ 0.2% (2 кадра). Побайтовый md5 на объёме отложен на ARQ/дуплекс (п.5) — решение §12.3; веха симплекса = PHY-линия + PER
  4. 2026-07-14: антенны на столе — PER 10 МБ ≈ 0.36%, свип TX gain (§12.4), рабочая точка 20 дБ; линия SNR-ограничена, целостность 100%
  5. FDD 868/915 двусторонняя + меры из docs/NOTES.md
  6. UDP-туннель поверх линка; затем web-настройка (libmicrohttpd)
  7. Видео (raw UDP, пакеты ≤1472 Б) — при устойчивом PER

11. Диагностика (шпаргалка)

Симптом Первое, что проверить
scp: sftp-server not found использовать scp -O
RX молчит частоты TX/RX, -g TX, антенны/кабель, RX gain
CRC бьётся, кадры находятся SNR: снизить полосу, амплитуду TX (-a 0.15)
md5 не сходится, CRC ок потерянные кадры → смотреть разрывы seq (#6)
Работает на малом трафике, падает под нагрузкой CPU-лимит: rate > 1.92 MSPS? второй процесс на ядре 0?
Loopback ок, дуплекс в эфире нет самоглушение FDD (раздел 6)

12. Журнал ввода в строй (commissioning)

Ввод в строй ведётся строго OTA (антенны с самого начала). Кабельный этап регламента отладки (§5.5) осознанно пропущен — фиксируется как отклонение.

12.1 Программные фиксы перед первым включением (2026-07-14)

Перед первой передачей закрыты DSP-техдолги, способные испортить приём даже при идеальном канале (детали и статусы — §9): удалён вредный внешний NCO-CFO-контур (#4), добавлена достоверная проверка целостности CRC32 поверх RS (#3), детектор пропусков seq (#6); TX переведён на partial-push + дренаж хвоста DMA (#5). PHY-параметры не менялись → бенчмарк §2 остаётся в силе.

12.2 Цифровой BIST-loopback (2026-07-14) — DSP-тракт без эфира

Цель: изолировать код/протокол от RF до первого выхода в эфир. Внутренний цифровой шлейф AD9361 (/sys/kernel/debug/iio/iio:device0/loopback = 1), TX и RX на одной плате (192.168.2.1), файл 100 КБ случайных данных, режим -c rs8.

Пауза TX (-p) Поймано/послано RS испр RS битых Потери seq md5 EVM
2 000 мкс 76/100 2 17 24 ✗ (дыры) 56 дБ
20 000 мкс 100/100 0 0 0 совпал 60 дБ

Вывод: DSP-пайплайн полностью исправен — при разгруженном RX 100% кадров приняты байт-в-байт, md5 совпал. Потери на паузе 2 мс — не баг фрейминга, а конкуренция за CPU: TX+RX+iiod на одной 2-ядерной плате; RX не успевает за эфиром и kernel роняет сэмплы (согласуется с бюджетом 1.22× из §2). В штатном двухплатном OTA у RX выделенное ядро — ожидается кратное снижение потерь. Проверка CRC-поверх-RS подтверждена в бою: 17 неисправимых кадров корректно отброшены (не ушли мусором в файл), 2 кадра реально восстановлены RS — счётчики rs_saved/rs_fail теперь достоверны (техдолг #3 закрыт по факту).

12.3 Первый двухплатный OTA (2026-07-14) — приём по воздуху

Антенны, симплекс 915 МГц, дистанция «на столе». RX на плате B (192.168.3.1), TX на A (192.168.2.1), TX gain 30 дБ. Опорники плат сведены достаточно: |CFO| ≈ 0.0005, синхронизатор ловит без ручного свипа частоты.

Тест Размер FEC -p Поймано RS испр RS бит Потери Вывод/послано md5 RSSI EVM
A 10 КБ none 5000 мкс 10 0 10/10 совпал 31 дБ 22.7 дБ
B 100 КБ rs8 2000 мкс 77 4 13 26 61/100 ✗ (дыры) 31 дБ 25.0 дБ
B 100 КБ rs8 6000 мкс 100 0 0 0 100/100 совпал 34 дБ 16.0 дБ
C 1 МБ rs8 6000 мкс 1022 0 0 2 1022/1024 ✗ (2 кадра) 30 дБ 26.8 дБ
D 10 МБ rs8 6000 мкс 10240 2 0 37 10203/10240 ✗ (37 кадров) 30 дБ 25.9 дБ

Главное: первый файл прошёл по воздуху байт-в-байт (тест A) — OTA-линия работоспособна. Радиоканал качественный: EVM 16…27 дБ, RSSI 30…34 дБ, CFO ≈ 0, пойманные кадры почти все декодируются.

Пропускная способность (тесты B→B): пауза 2 мс теряет ~39% кадров, 6 мс — 0%. Причём на двух платах с выделенными ядрами, значит это не CPU-contention из §12.2. Причина конструктивная: receiver однопоточный — RS-декод выполняется inline в callback синхронизатора и отнимает его пропускную способность. Запас 1.22× (§2) не покрывает добавленную стоимость RS при сплошном потоке; троттлинг TX паузой -p 6000 возвращает систематическую потерю в ноль (100 КБ — 100/100).

Остаточный PER (тесты C, D): 0.2% на 1 МБ (2/1024) и 0.36% на 10 МБ (37/10240). Это уже не throughput (кадры не накапливаются, RS битых: 0 на всех объёмах), а спорадические одиночные пропуски. RS битых: 0 на 10 МБ — важно: проверка CRC- поверх-RS ни разу не пропустила мусор в файл, а RS дважды реально исправил ошибки (тест D). При симплексе без ARQ пропущенный кадр — молчаливая дыра (техдолг #6), поэтому md5 на объёме не сходится, хотя PHY-линия по факту надёжна (PER ≈ 0.3%, целостность 100%). CPU RX справляется: PER не растёт с объёмом → отставание не накапливается.

Дальнейшие рычаги: (1) устойчивая передача файла требует избыточности — на симплексе это forward-redundancy (TX гонит файл N раз, RX пишет кадры по seq в нужное смещение, дыры заполняются за проходы), полноценный ARQ — на этапе дуплекса (§10 п.5); (2) двухпоточный конвейер RX (BENCHMARK §«резервы» п.2) — поднимет throughput и позволит убрать паузу. test_file_link.sh теперь с параметрами PAUSE/FEC/TXGAIN. Рычаг (2) реализован и опровергнут — см. §12.5.

Решение (2026-07-14): побайтовый лосслесс на объёме отложен на этап дуплекса — там ставится полноценный ARQ с обратным каналом (§10 п.5). На текущем симплекс- этапе forward-redundancy не внедряем; веха этапа — работоспособная PHY-линия и измеренный PER.

12.4 Свип TX gain — карта PER/EVM (2026-07-14)

1 МБ, rs8, -p 6000, дистанция «на столе», симплекс 915 МГц.

TX gain RSSI EVM Потери seq RS испр RS бит PER (потери) Примечание
40 дБ 45 дБ 15.0 дБ 33 27 41 ~3.2% (+41 неиспр) SNR-floor: RS активно спасает, но 41 блок неисправим
30 дБ 31 дБ 24.8 дБ 5 0 1 0.49% рабочая зона
20 дБ 22 дБ 32.9 дБ 3 0 0 0.29% рабочая точка (запас в обе стороны)
10 дБ 11 дБ 39.7 дБ 1 0 0 0.10% лучший PER; вход RX ещё не насыщен

Выводы:

  • Линия SNR-ограничена, а не насыщением: EVM монотонно улучшается 15 → 40 дБ с ростом мощности; насыщения входа RX (усиление 50 дБ фикс.) не видно даже при RSSI 11 дБ. Потолок по gain на этой геометрии не достигнут.
  • PER падает с мощностью: 3.2% (40) → 0.1% (10). Плато 20…10 дБ даёт PER 0.10.3% при EVM 33…40 дБ, RS даже не требуется (0 неисправимых).
  • RS реально работает под нагрузкой: на 40 дБ спас 27 кадров, забракованных liquid-CRC. До фикса #3 они ушли бы мусором или фиктивно «спасёнными» — это боевое подтверждение всей FEC-цепочки (libfec + CRC-поверх-RS).
  • Рабочая точка симплекса: TX gain 20 дБ (PER 0.29%, EVM 33 дБ, запас по SNR вниз и до насыщения вверх); для максимальной надёжности на этой дистанции 10 дБ.

Итог симплекс-этапа: PHY OTA-линия работает и охарактеризована по мощности, целостность 100% (мусор в файл не попадает), PER ≈ 0.10.3% в рабочей зоне. Остаток к «надёжной побайтовой» передаче = ARQ на этапе дуплекса (§10 п.5).

12.5 Двухпоточный RX и диагностика паузы (2026-07-14)

Реализован двухпоточный RX (поток A: refill+convert на ядре 1; поток B: sync+RS на ядре 0, кольцо 16×32768). Цель — убрать TX-паузу -p 6000НЕ достигнута: на 1 МБ чисто только при -p 8000 (хуже базы §12.4), на низких паузах кольцо переполняется (столбец Overrun).

Диагностика через расширенный ofdm_bench (разбивка стадий, см. docs/BENCHMARK.md «Разбивка стоимости по стадиям»):

Замер (плата B, ядро 0) Результат Вывод
sync-only, сплошные кадры (-g 0) 1.65 Msps < 1.92 синхронизатор сам не realtime при duty→1; -p 0 недостижим
«запас 1.22×» из §2 артефакт duty 0.571 под сплошным потоком запаса нет
только конвертация 85 Msps (~2% нагрузки B) вынос конвертации (что и дал двухпоток) почти бесполезен
RS-декод 275 мкс/блок = 26% эфира кадра крупнейшая переносимая стоимость; «RS мал» (§2) опровергнуто
контеншн L2/DDR (-H) 0.2% кэш-гипотеза отвергнута; ядро 1 свободно под RS

Диагноз: узкое место — не захват (конвертация бесплатна) и не кэш, а сам sync + RS на одном ядре. Двухпоток вынес не то (конвертацию, ~2%), оставив RS (26%) на ядре синхронизатора.

План: 3-стадийный конвейер — ядро 0: только sync; ядро 1: refill+conv+RS +запись. Модель p_min: ~3.4 мс (сейчас) → ~1.3 мс → ~45× к throughput. Абсолютный -p 0 на этом PHY недостижим (нужен M=32/CP=8 или ARQ). Реализация 3-стадии — следующий шаг.


Ввод в строй: 2026-07-14. Замеры CPU и базовые решения — 2026-07-10. Прошивка v0.38, liquid-dsp 1.8.0.

Description
Цифровая радиолиния точка-точка на базе двух ADALM-Pluto+ (клон, Zynq-7020). PHY: OFDM (liquid-dsp) + RS(255,223) FEC. Весь сигнальный тракт исполняется на ARM Cortex-A9 внутри Pluto; хост-ПК нужен только для сборки, заливки бинарей и снятия логов. Прототип в рамках ОКР «R-Link» (двухранговая самоорганизующаяся сеть); данный репозиторий покрывает уровень PHY/линка.
Readme 253 KiB
Languages
C 78.2%
Shell 19.5%
Makefile 2.3%