Initial commit: OFDM-радиолиния на двух Pluto+ (PHY/link, код на ARM)

- src: transmitter, receiver, ofdm_bench, common (libiio local: + liquid-dsp)
- scripts: кросс-сборка зависимостей, деплой scp -O, e2e-тест с md5
- docs: бенчмарк CPU (выбор rate 1.92 MSPS), грабли FDD/регуляторика
- все текстовые файлы нормализованы в LF (.gitattributes принудительно):
  CRLF в toolchain.env/makefile ломал source и make на Linux
- .vscode: IntelliSense в режиме linux-gcc-arm, заголовки из .xarm/include

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Maxim
2026-07-10 11:00:38 +03:00
commit 0f207b146d
18 changed files with 1579 additions and 0 deletions

68
scripts/test_file_link.sh Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
# test_file_link.sh — e2e-тест: файл → Pluto A → эфир → Pluto B → md5
# Использование: scripts/test_file_link.sh [ipA] [ipB] [размер_КБ]
# По умолчанию: адреса из toolchain.env, файл 1024 КБ, симплекс 915 МГц.
#
# ВНИМАНИЕ: сначала кабель + аттенюатор 3040 дБ (TX gain 40)!
set -euo pipefail
source "$(dirname "$0")/../toolchain.env"
A="${1:-$PLUTO_A}" # передатчик
B="${2:-$PLUTO_B}" # приёмник
SIZE_KB="${3:-1024}"
FREQ=915000000
RATE=1920000 # НЕ поднимать: бюджет CPU, docs/BENCHMARK.md
BW=1500000
TXGAIN=-40 # для кабеля; антенны: 20…0
TIMEOUT=$(( SIZE_KB / 100 + 30 )) # ~160 КБ/с + запас
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 "=== [1/5] Тестовый файл ${SIZE_KB} КБ ==="
dd if=/dev/urandom of=/tmp/link_test.bin bs=1024 count="$SIZE_KB" status=none
MD5_SRC=$(md5sum /tmp/link_test.bin | cut -d' ' -f1)
echo "md5: $MD5_SRC"
echo "=== [2/5] Заливка файла на Pluto A ($A) ==="
"${SCP[@]}" /tmp/link_test.bin "root@$A:/tmp/"
echo "=== [3/5] Старт приёмника на Pluto B ($B), таймаут ${TIMEOUT}с ==="
"${SSH[@]}" "root@$B" \
"rm -f /tmp/out.bin; timeout $TIMEOUT /tmp/receiver -f $FREQ -r $RATE \
-b $BW -c rs8 -u local: > /tmp/out.bin 2>/tmp/rx.log" &
RX_PID=$!
sleep 3 # дать RX прогреться до старта TX
echo "=== [4/5] Передача с Pluto A ==="
"${SSH[@]}" "root@$A" \
"cat /tmp/link_test.bin | /tmp/transmitter -f $FREQ -r $RATE -b $BW \
-g $TXGAIN -p 0 -c rs8 -u local: 2>/tmp/tx.log"
sleep 3 # дохлебать хвост эфира
"${SSH[@]}" "root@$B" "killall receiver 2>/dev/null || true"
wait "$RX_PID" 2>/dev/null || true
echo "=== [5/5] Сверка ==="
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 байт)"
if [ "$MD5_SRC" = "$MD5_DST" ]; then
echo "РЕЗУЛЬТАТ: OK — файл передан без искажений"
else
echo "РЕЗУЛЬТАТ: FAIL"
echo "Диагностика (README §11):"
echo " - размер меньше исходного → потерянные кадры (нет ARQ, техдолг #6):"
echo " смотри лог RX и разрывы seq"
echo " - размер равен, md5 нет → техдолг #1 (header_len=12?) или #3"
echo " - размер 0 → RX не поймал ничего: частота/усиление/кабель"
"${SSH[@]}" "root@$B" "tail -5 /tmp/rx.log" || true
fi