docs: group-FEC 16+2 задокументирован, рабочая точка соука -p 4000 (§12.7)
- README §12.7 — журнал этапа (расчёт 16+2, таблица прогонов, находка overrun) - README §10 — перенумерация: п.6=group-FEC, ARQ/FDD→п.7, туннель→п.8, видео→п.9 - README §9 — техдолг #6 обновлён (group-FEC закрывает симплекс-потери) - docs/BENCHMARK.md, CLAUDE.md, test_file_link.sh — соук-точка -p 4000 - transmitter.c — снят -Wdiscarded-qualifiers на crc_generate_key (const-каст)
This commit is contained in:
88
README.md
88
README.md
@@ -235,7 +235,7 @@ ssh root@192.168.2.1 '/tmp/ofdm_bench 1.92'
|
||||
| 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 ещё нет |
|
||||
| 6 | Нет ARQ: потерянный кадр = молчаливая дыра в файле. seq в заголовке есть, но RX его игнорирует | ⚙️ частично: детектор пропусков seq (лог `[ПОТЕРЯ]` + счётчик) + **групповой стирающий FEC 16+2 закрывает ≤2 потери/группу на симплексе без обратного канала (§12.7, п.6)**; полный ARQ — на дуплексе (п.7) |
|
||||
|
||||
## 10. Дорожная карта
|
||||
|
||||
@@ -247,17 +247,23 @@ ssh root@192.168.2.1 '/tmp/ofdm_bench 1.92'
|
||||
✅ первый OTA-приём — 10 КБ байт-в-байт, EVM −22.7 дБ (§12.3)
|
||||
✅ пауза `-p 6000` убрала throughput-потери (100 КБ — 100/100);
|
||||
на 1 МБ остаточный PER ≈ 0.2% (2 кадра). Побайтовый md5 на объёме отложен
|
||||
на ARQ/дуплекс (п.6) — решение §12.3; веха симплекса = PHY-линия + PER
|
||||
на ARQ/дуплекс (п.7) — решение §12.3; веха симплекса = PHY-линия + PER
|
||||
4. ✅ антенны на столе — PER 10 МБ ≈ 0.36%, свип TX gain (§12.4),
|
||||
рабочая точка −20 дБ; линия SNR-ограничена, целостность 100%
|
||||
5. ✅ **3-стадийный RX-конвейер** (§12.6): ядро 0 — только
|
||||
`ofdmflexframesync_execute`; ядро 1 — refill+конвертация **и RS-декод**.
|
||||
Рабочая пауза `-p 6000` → `-p 3000`, throughput 90 → 120 КБ/с (**×1.36**),
|
||||
FQ drops 0 (RS не узкое место). `-p 0` на этом PHY недостижим — осознанное
|
||||
ограничение; побайтовый лосслесс — через ARQ (п.6).
|
||||
6. FDD 868/915 двусторонняя + ARQ с обратным каналом + меры из docs/NOTES.md
|
||||
7. UDP-туннель поверх линка; затем web-настройка (libmicrohttpd)
|
||||
8. Видео (raw UDP, пакеты ≤1472 Б) — при устойчивом PER
|
||||
ограничение; побайтовый лосслесс на симплексе — групповым FEC (п.6, §12.7).
|
||||
6. ✅ **Групповой стирающий FEC 16+2** (§12.7): восстановление молчаливых
|
||||
потерь кадров БЕЗ обратного канала (RAID-6-стиль P+Q над GF(256): 16 кадров
|
||||
данных + 2 паритета, закрывает ≤2 стёртых кадра/группу). Соук 10 МБ
|
||||
байт-в-байт на рабочей точке `-p 4000`. Защита информации (лёгкий AEAD,
|
||||
+16 Б/кадр, <1% CPU) — отложена, требования ОКР «R-Link» нет; формат
|
||||
с резервом под неё.
|
||||
7. FDD 868/915 двусторонняя + ARQ с обратным каналом + меры из docs/NOTES.md
|
||||
8. UDP-туннель поверх линка; затем web-настройка (libmicrohttpd)
|
||||
9. Видео (raw UDP, пакеты ≤1472 Б) — при устойчивом PER
|
||||
|
||||
## 11. Диагностика (шпаргалка)
|
||||
|
||||
@@ -340,13 +346,13 @@ TX паузой `-p 6000` возвращает систематическую п
|
||||
Дальнейшие рычаги: (1) **устойчивая передача файла** требует избыточности —
|
||||
на симплексе это forward-redundancy (TX гонит файл N раз, RX пишет кадры по
|
||||
`seq` в нужное смещение, дыры заполняются за проходы), полноценный ARQ — на этапе
|
||||
дуплекса (§10 п.6); (2) двухпоточный конвейер RX (BENCHMARK §«резервы» п.2) —
|
||||
дуплекса (§10 п.7); (2) двухпоточный конвейер RX (BENCHMARK §«резервы» п.2) —
|
||||
поднимет throughput и позволит убрать паузу. `test_file_link.sh` теперь с
|
||||
параметрами `PAUSE`/`FEC`/`TXGAIN`. **Рычаг (2) реализован и опровергнут —
|
||||
см. §12.5.**
|
||||
|
||||
**Решение (2026-07-14):** побайтовый лосслесс на объёме отложен на этап дуплекса —
|
||||
там ставится полноценный ARQ с обратным каналом (§10 п.6). На текущем симплекс-
|
||||
там ставится полноценный ARQ с обратным каналом (§10 п.7). На текущем симплекс-
|
||||
этапе forward-redundancy не внедряем; веха этапа — работоспособная PHY-линия и
|
||||
измеренный PER.
|
||||
|
||||
@@ -375,7 +381,8 @@ TX паузой `-p 6000` возвращает систематическую п
|
||||
|
||||
**Итог симплекс-этапа:** PHY OTA-линия работает и охарактеризована по мощности,
|
||||
целостность 100% (мусор в файл не попадает), PER ≈ 0.1–0.3% в рабочей зоне.
|
||||
Остаток к «надёжной побайтовой» передаче = ARQ на этапе дуплекса (§10 п.6).
|
||||
Остаток к «надёжной побайтовой» передаче на симплексе закрыт групповым FEC
|
||||
(§12.7, §10 п.6); полный ARQ — на этапе дуплекса (§10 п.7).
|
||||
|
||||
### 12.5 Двухпоточный RX и диагностика паузы (2026-07-14)
|
||||
|
||||
@@ -436,8 +443,67 @@ docs/BENCHMARK.md «Разбивка стоимости по стадиям»):
|
||||
~90 КБ/с на `-p 6000` = **×1.36** (не ×4–5 — эфир кадра 5.33 мс доминирует над
|
||||
паузой; прежняя оценка исправлена).
|
||||
- `-p 0` по-прежнему недостижим (sync сам 0.86× realtime, §12.5) — осознанное
|
||||
ограничение PHY, лосслесс на объёме — через ARQ (§10 п.6).
|
||||
ограничение PHY, лосслесс на объёме — групповым FEC (§12.7) или ARQ (§10 п.7).
|
||||
|
||||
### 12.7 Групповой стирающий FEC 16+2 (§10 п.6) — 2026-07-15
|
||||
|
||||
Симплекс закрывает молчаливые потери кадров БЕЗ обратного канала (ARQ требует
|
||||
дуплекса, п.7). Потери одиночные и с известной позицией (из seq) — это
|
||||
*стирания*, поэтому оптимально стирающее кодирование, а не дублирование.
|
||||
|
||||
**Метод (по расчёту).** Группа = 16 кадров данных + 2 паритета над GF(256)
|
||||
(полином 0x11d, генератор g=2, RAID-6-стиль): P = ⊕dᵢ, Q = ⊕gⁱ·dᵢ. Позиции
|
||||
стираний известны → 2 паритета закрывают ≤2 стёртых кадра на группу.
|
||||
|
||||
| Вариант | Overhead | Остаток на 10 МБ (PER 0.26%) |
|
||||
|---|---|---|
|
||||
| Дублирование 2× | 100% | ~0.07 кадра |
|
||||
| XOR 16+1 | 6.25% | ~0.6 группы — НЕ лосслесс |
|
||||
| **16+2 (выбрано)** | **12.5%** | **~0.009 группы** → ~99% передач байт-в-байт |
|
||||
|
||||
Формат: hdr[11] (был резерв) = флаги `[bit7 GF_MODE][bit6 GF_PARITY][bit5 GF_Q]
|
||||
[bits4-0 idx 0..17]`; hdr[11]=0 = legacy (RX автодетект по первому кадру, старый
|
||||
путь не тронут). Паритетный кадр несёт 1026 Б (2 Б меты `k′`/`tail_len`
|
||||
+ 1024 Б паритета) → те же 5 RS-блоков (1275 Б в эфире), что и данные →
|
||||
геометрия PHY не меняется, бенчмарк §2 в силе (правило №6 не срабатывает).
|
||||
GF-математика самопроверена офлайн: `make gftest` — **774400 кейсов** (все
|
||||
`k=1..16`, все пары стираний, все комбинации наличия P/Q), **0 ошибок**.
|
||||
Стоимость GF-кодека < 0.2% ядра, ложится в поток C (RS).
|
||||
|
||||
**Прогоны OTA (2026-07-15, TXGAIN −20, симплекс 915 МГц):**
|
||||
|
||||
| Тест | Размер | `-p` | Потери seq | Overrun | GF восст | GF провал | md5 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| Регрессия legacy (`GROUPFEC=0`) | 1 МБ | 3000 | 0 | 0 | — | — | ✅ |
|
||||
| Group | 1 МБ | 3000 | 4 | 0 | 4 | 0 | ✅ |
|
||||
| Group стресс (−29 дБ) | 1 МБ | 3000 | 3 | 0 | 3 | 0 | ✅ |
|
||||
| **Соук** | 10 МБ | 3000 | 208 | **62** | 38 | **44** | ✗ |
|
||||
| Диагностика legacy (`GROUPFEC=0`) | 10 МБ | 3000 | 213 | 63 | — | — | ✗ |
|
||||
| **Соук** | 10 МБ | 4000 | 33 | **0** | 31 | **0** | ✅ **байт-в-байт** |
|
||||
|
||||
**Ключевая находка — overrun рвёт стирающий FEC на длинной дистанции.**
|
||||
Соук на `-p 3000` дал **44 провала группы** против ~6 по независимой модели
|
||||
(λ=0.42 стирания/группу, Пуассон) = **×7 сверх ожидания** → потери
|
||||
**кластеризуются в пачки**, а не рассыпаны. Источник — 62 overrun ядра 0:
|
||||
каждый роняет подряд идущие seq = подряд идущие idx одной группы, пробивая
|
||||
бюджет ≤2. Диагностика (`GROUPFEC=0`, тот же 10 МБ) дала те же 63 overrun и
|
||||
2.7% потерь → **срыв ядра 0 присущ sustained-соуку сам по себе, group-FEC ни
|
||||
при чём**; рабочая точка `-p 3000` из §12.6 снята на коротких прогонах и на
|
||||
10 МБ-соук не переносится (поток B не держит realtime на непрерывном потоке
|
||||
дольше).
|
||||
|
||||
**`-p 4000` даёт ядру 0 запас → Overrun 0 → чистый floor** (33 стирания на
|
||||
640 групп = λ=0.05, независимые одиночные) → 16+2 закрыл всё с запасом
|
||||
(GF провал 0), **10 МБ байт-в-байт**. Интерливер (разнос кадров группы против
|
||||
пачек) оказался **не нужен**: убрав overrun паузой, получили редкие
|
||||
независимые стирания, где у 16+2 колоссальный margin.
|
||||
|
||||
**Рабочая точка group-FEC / длинных передач: `-p 4000`** (~95 КБ/с; цена
|
||||
против `-p 3000` — ~12 КБ/с за Overrun 0 и лосслесс). Короткие передачи
|
||||
(≤1 МБ) остаются рабочими на `-p 3000` (§12.6). Защита информации (лёгкий
|
||||
AEAD, +16 Б/кадр, <1% CPU) — отложена, требования ОКР «R-Link» нет; формат
|
||||
кадра с резервом под неё.
|
||||
|
||||
---
|
||||
*Ввод в строй: 14-07-2026. Замеры CPU и базовые решения — 10-07-2026.
|
||||
*Ввод в строй: 14–15-07-2026. Замеры CPU и базовые решения — 10-07-2026.
|
||||
Прошивка v0.38, liquid-dsp 1.8.0.*
|
||||
Reference in New Issue
Block a user