From b5bf0c7b18a2416251a0164bca1405977299a607 Mon Sep 17 00:00:00 2001 From: Maxim Date: Thu, 16 Jul 2026 10:50:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=AD=D1=82=D0=B0=D0=BF=201.=20=D0=98=D0=B4?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=B4=D0=B0=D0=BB=D1=8C=D1=88=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/test_fdd_fwd.sh | 96 +++++++++++++++++++++++++++++++++++++++++ src/common.c | 11 ++++- 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 scripts/test_fdd_fwd.sh diff --git a/scripts/test_fdd_fwd.sh b/scripts/test_fdd_fwd.sh new file mode 100644 index 0000000..8d6f9b7 --- /dev/null +++ b/scripts/test_fdd_fwd.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# test_fdd_fwd.sh — e2e-тест форвард-линка ПОД FDD (этап 1, §10 п.7). +# Данные A→B на 915; обе платы открывают оба cf-девайса (флаг -F). Обратного +# трафика ещё нет (этап 2) — feedback-TX приёмника лишь СКОНФИГУРИРОВАН. +# Цель теста: доказать, что форвард-линк выживает, когда оба чипа в FDD и оба +# LO активны, и замерить самоглушение (NOTES §2) свипом FBGAIN. +# +# Использование: scripts/test_fdd_fwd.sh [ipA] [ipB] [размер_КБ] +# FBGAIN=-89 (дефолт) — feedback-TX платы B практически заглушён (базовый прогон) +# FBGAIN=-20 — штатное усиление обратного канала (проверка десенса RX B) +# FBFREQ, PAUSE, TXGAIN, FEC, GROUPFEC — как в test_file_link.sh +# ВНИМАНИЕ: сначала кабель + аттенюатор 30–40 дБ! +set -euo pipefail +source "$(dirname "$0")/../toolchain.env" + +A="${1:-$PLUTO_A}" # передатчик данных (TX 915 / fb-RX 868) +B="${2:-$PLUTO_B}" # приёмник данных (RX 915 / fb-TX 868) +SIZE_KB="${3:-1024}" + +FREQ=915000000 # несущая данных +FBFREQ="${FBFREQ:-868000000}" # несущая обратного канала (fb-RX у A, fb-TX у B) +RATE=1920000 # НЕ поднимать: бюджет CPU, docs/BENCHMARK.md +BW=1500000 +TXGAIN="${TXGAIN:--30}" # усиление TX данных на плате A +FBGAIN="${FBGAIN:--89}" # усиление feedback-TX на плате B. −89 ≈ выкл (база), + # −20 — штатный обратный канал (гипотеза самоглушения) +FEC="${FEC:-rs8}" +PAUSE="${PAUSE:-4000}" # §12.7: соук/маргинальный канал — только 4000, не 3000 +GROUPFEC="${GROUPFEC:-1}" +[ "$GROUPFEC" = 1 ] && GFLAG="-G" || GFLAG="" +if [ "$GROUPFEC" = 1 ]; then TIMEOUT=$(( SIZE_KB / 85 + 20 )); else TIMEOUT=$(( SIZE_KB / 95 + 20 )); fi + +if command -v sshpass >/dev/null; then + SSH=(sshpass -p "$PLUTO_PASS" ssh -o StrictHostKeyChecking=no) + SCP=(sshpass -p "$PLUTO_PASS" scp -O -o StrictHostKeyChecking=no) +else + SSH=(ssh); SCP=(scp -O) + echo "подсказка: apt install sshpass — и пароль вводить не придётся" +fi + +echo "=== FDD форвард-линк: A=$A (TX $((FREQ/1000000))/fb-RX $((FBFREQ/1000000))) → B=$B (RX данных) ===" +echo " FBGAIN=$FBGAIN дБ PAUSE=$PAUSE GROUPFEC=$GROUPFEC FEC=$FEC" + +echo "=== [1/6] Тестовый файл ${SIZE_KB} КБ ===" +dd if=/dev/urandom of=/tmp/fdd_test.bin bs=1024 count="$SIZE_KB" status=none +MD5_SRC=$(md5sum /tmp/fdd_test.bin | cut -d' ' -f1) +echo "md5: $MD5_SRC" + +echo "=== [2/6] Зачистка хвостов на обеих платах ===" +"${SSH[@]}" "root@$A" "killall -9 transmitter receiver 2>/dev/null || true" +"${SSH[@]}" "root@$B" "killall -9 transmitter receiver 2>/dev/null || true" + +echo "=== [3/6] Заливка файла на Pluto A ($A) ===" +"${SCP[@]}" /tmp/fdd_test.bin "root@$A:/tmp/" + +echo "=== [4/6] Старт приёмника на Pluto B ($B) в FDD, таймаут ${TIMEOUT}с ===" +# busybox без `timeout` → сторожевой sleep+kill на самой плате. +# Приёмник данных на 915 + feedback-TX 868 сконфигурирован (-F/-g). +"${SSH[@]}" "root@$B" \ + "rm -f /tmp/out.bin; /tmp/receiver -f $FREQ -r $RATE -b $BW -c $FEC \ + -F $FBFREQ -g $FBGAIN -u local: > /tmp/out.bin 2>/tmp/rx_fdd.log & \ + RXP=\$!; (sleep $TIMEOUT; kill \$RXP 2>/dev/null) & wait \$RXP" & +RX_PID=$! +sleep 4 # дать RX прогреться (FDD-инициализация двух трактов дольше) + +echo "=== [5/6] Передача с Pluto A в FDD ===" +"${SSH[@]}" "root@$A" \ + "cat /tmp/fdd_test.bin | /tmp/transmitter -f $FREQ -r $RATE -b $BW \ + -g $TXGAIN -p $PAUSE -c $FEC $GFLAG -F $FBFREQ -u local: 2>/tmp/tx_fdd.log" +sleep 3 # дохлебать хвост эфира +"${SSH[@]}" "root@$B" "killall receiver 2>/dev/null || true" +wait "$RX_PID" 2>/dev/null || true + +echo "=== [6/6] Сверка ===" +MD5_DST=$("${SSH[@]}" "root@$B" "md5sum /tmp/out.bin 2>/dev/null | cut -d' ' -f1" || echo "нет_файла") +SIZE_DST=$("${SSH[@]}" "root@$B" "wc -c < /tmp/out.bin 2>/dev/null" || echo 0) + +echo "источник: $MD5_SRC ($((SIZE_KB*1024)) байт)" +echo "приёмник: $MD5_DST ($SIZE_DST байт)" + +# Ридбэк LO обеих плат — подтверждение, что FDD-тракты поднялись +echo "--- FDD-ридбэк ---" +"${SSH[@]}" "root@$A" "grep 'FDD ридбэк' /tmp/tx_fdd.log 2>/dev/null | sed 's/^/A: /'" || true +"${SSH[@]}" "root@$B" "grep 'FDD ридбэк' /tmp/rx_fdd.log 2>/dev/null | sed 's/^/B: /'" || true + +if [ "$MD5_SRC" = "$MD5_DST" ]; then + echo "РЕЗУЛЬТАТ: OK — форвард-линк под FDD цел (FBGAIN=$FBGAIN)" +else + echo "РЕЗУЛЬТАТ: FAIL (FBGAIN=$FBGAIN)" + echo "Диагностика:" + echo " - размер 0 → RX под FDD не декодит: самоглушение? Прогони FBGAIN=-89." + echo " - размер < исходного → потери кадров (ARQ ещё нет, этап 3)." + echo " - EVM в хвосте rx_fdd.log ниже −10 дБ → десенс RX: снизь FBGAIN/RX gain." + echo "--- хвост rx_fdd.log (B) ---" + "${SSH[@]}" "root@$B" "tail -6 /tmp/rx_fdd.log" || true +fi diff --git a/src/common.c b/src/common.c index e91722a..894f231 100644 --- a/src/common.c +++ b/src/common.c @@ -4,6 +4,10 @@ #include "common.h" +// Допуск сверки ридбэка LO с заданием (Гц). AD9361-синтезатор округляет к +// достижимой сетке (~2 Гц шаг) — точное равенство давало бы ложную ошибку. +#define FDD_LO_TOL_HZ 100 + volatile sig_atomic_t stop = 0; static void sigint_handler(int s) { @@ -188,8 +192,11 @@ int pluto_configure_fdd(struct iio_device *phy, long long tx_freq, iio_device_attr_read(phy, "ensm_mode", ensm, sizeof(ensm)); fprintf(stderr, "FDD ридбэк: TX LO %.3f МГц | RX LO %.3f МГц | ENSM=%s\n", tx_rb / 1e6, rx_rb / 1e6, ensm[0] ? ensm : "?"); - if (tx_rb != tx_freq || rx_rb != rx_freq) - LOG_ERROR("ридбэк LO не совпал: TX %lld≠%lld или RX %lld≠%lld", + // AD9361 — дробный-N синтезатор с шагом ~2 Гц: ридбэк округляется к + // достижимой частоте (868000000 → 867999998). Это НЕ ошибка. Допуск 100 Гц + // ловит реальные промахи (кГц/МГц-масштаба), игнорируя округление PLL. + if (llabs(tx_rb - tx_freq) > FDD_LO_TOL_HZ || llabs(rx_rb - rx_freq) > FDD_LO_TOL_HZ) + LOG_ERROR("ридбэк LO не совпал: TX %lld (задано %lld) | RX %lld (задано %lld)", tx_rb, tx_freq, rx_rb, rx_freq); if (ensm[0] && strncmp(ensm, "fdd", 3) != 0) LOG_ERROR("ENSM=%s (не fdd) — одновременный TX+RX не гарантирован", ensm);