Полное дерево LibreVNA v1.6.5 с доработками master/slave, эталонные битстримы и прошивки STM32, упаковщик .vnafw. Проверено: build.sh пересобирает обе прошивки побайтово идентично лежащим рядом .vnafw. Мастер-битстрим (top_master.bin / extracted/master_fpga.bin) больше нигде не существует — place&route в ISE недетерминирован, из исходников он не восстанавливается. Положено в multi_libreVNA_firmware/reproduce, а не в device_firmware/reproduce как сказано в README комплекта: SHA256SUMS и build.sh ссылаются на ../combined.vnafw, а .vnafw лежат здесь. Корневые правила .gitignore build*/build/ выбрасывали 482 файла, включая сам build.sh и эталонные прошивки STM32 из SHA256SUMS — дописано разыгноривание. Оставшиеся 7 файлов перебивал вложенный апстримный .gitignore (более глубокий имеет приоритет), они добавлены force-add'ом. Промежуточные .o/.d/.su из build-каталогов убраны, .bin/.elf/.hex/.map оставлены. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
11 KiB
Воспроизведение прошивок LibreVNA
Здесь всё, что нужно, чтобы пересобрать прошивки из device_firmware/ с нуля.
Проект лежит целиком — не патч, а полное дерево с уже внесёнными доработками.
Что где
reproduce/
├── LibreVNA/ полный проект: апстрим v1.6.5 + доработки master/slave
│ ├── Software/VNA_embedded/ прошивка STM32G431CBUx (CubeIDE + Makefile)
│ │ ├── build/ собранный мастер (VNA_embedded.bin/.elf/.map)
│ │ └── build_external_lo_slave/ собранный slave
│ ├── FPGA/VNA/ VHDL-проект под Xilinx ISE 14.7
│ │ ├── top_master.bin битстрим мастера ← из combined.vnafw
│ │ ├── top_external_lo_slave.bin битстрим slave
│ │ └── top.bin СТОКОВЫЙ апстримный, не наш (см. ниже)
│ └── AssembleFirmware.py упаковщик .vnafw
├── extracted/ секции, вынутые из готовых .vnafw
├── build.sh пересборка + сверка с эталоном
└── SHA256SUMS эталонные хеши (sha256sum -c SHA256SUMS)
Из LibreVNA/ исключены только .git (снапшот с одним коммитом init, истории правок
в нём нет) и .venv.
Железо и версии
| MCU | STM32G431CBUx, Cortex-M4, 128 КБ флеш / 32 КБ RAM |
| Линкер | STM32G431CBUX_FLASH.ld, образ с 0x08000000 |
| FPGA | Xilinx, битстрим 341 712 Б, проект под ISE 14.7 |
| Версия ПО | FW 1.6.5, HW_REVISION='B' (задано в Makefile) |
| Тулчейн STM32 | STM32CubeIDE 1.17.0, gcc arm-none-eabi 12.3.1 |
| Апстрим | github.com/jankae/LibreVNA, тег v1.6.5 |
Две сборки
Различие мастер/slave — один флаг, отдельных веток кода нет.
| STM32 | FPGA | |
|---|---|---|
| мастер | make (EXTERNAL_MASTER_LO_SLAVE=0) |
проект VNA.xise → BuildConfig.vhd (false) |
| slave | make EXTERNAL_MASTER_LO_SLAVE=1 |
VNA_external_lo_slave.xise → BuildConfig_external_lo_slave.vhd (true) |
Два .xise отличаются ровно одной строкой — каким из двух BuildConfig подключаться.
Формат .vnafw
Заголовок 24 байта, little-endian (см. AssembleFirmware.py):
| Смещение | Поле |
|---|---|
| 0x00 | магия VNA! |
| 0x04 | смещение FPGA-битстрима (всегда 24) |
| 0x08 | размер FPGA-битстрима |
| 0x0C | смещение прошивки MCU (= 24 + размер FPGA) |
| 0x10 | размер прошивки MCU |
| 0x14 | CRC32 по (битстрим + прошивка MCU), начальное значение 0xFFFFFFFF |
Дальше подряд битстрим и прошивка MCU, хвост добит нулями до кратности 256.
Разложить готовый файл на части:
tail -c +25 combined.vnafw | head -c 341712 > top.bin # FPGA
tail -c +341737 combined.vnafw | head -c 85004 > VNA_embedded.bin # STM32
Отличия от апстрима v1.6.5
Всего 12 файлов. Всё остальное дерево совпадает с апстримом байт в байт.
STM32 — поддержка аппаратного триггера (это и есть съём без USB)
Application/Trigger.cpp (+45/−3) — главное изменение, работает в обеих сборках.
В апстриме Trigger::Init() только вешал EXTI на FPGA_TRIGGER_OUT, а FPGA_TRIGGER_IN
всегда оставался выходом STM (триггер эмулировался по USB). Добавлены
ConfigureInputPin() / ConfigureOutputMonitorPin(), которые в режиме Mode::Trigger
(syncMode = 3) убирают STM с обеих линий:
FPGA_TRIGGER_IN→ вход без подтяжки: линию гонит внешняя триггер-петля, а не STM;FPGA_TRIGGER_OUT→ вход без подтяжки, EXTI снимается: FPGA драйвит линию напрямую на второе устройство.
В остальных режимах поведение прежнее. Конфигурация пинов теперь вызывается и из
Trigger::SetMode(), а не только при инициализации.
Application/Hardware.cpp (+29/−2) — в HW::SetIdle() вместо Trigger::SetInput(false)
теперь Trigger::SetMode(Trigger::Mode::Off) (безусловно, обе сборки). Остальное под
#if EXTERNAL_MASTER_LO_SLAVE: гасится Si5351-канал LO1, LO1 не инициализируется как PLL,
статус LO1 всегда «locked», температура LO1 = 0.
Application/VNA.cpp (+33/−6) — вынесены UpdateLO1ReferenceClock() /
DisableLO1ReferenceClock(); в slave-сборке VNA::Setup() отклоняет свип, если
syncMode != Trigger или syncMaster != 0. Плюс безусловный багфикс: клампы points и
dwell_time применялись к старому settings вместо нового s.
Application/App.cpp (+28/−1) — только под #if EXTERNAL_MASTER_LO_SLAVE: slave
отвечает Nack на ManualControl, Generator, SpectrumAnalyzerSettings и на свипы,
не проходящие ExternalLOSlaveSweepSupported(). Также SweepSettings теперь отвечает
Nack, если VNA::Setup() вернул false.
Application/Hardware.hpp (+3) — дефолт EXTERNAL_MASTER_LO_SLAVE 0.
Makefile (+2) — EXTERNAL_MASTER_LO_SLAVE ?= 0 и проброс в -D.
FPGA — глушение LO1 в slave
FPGA/VNA/top.vhd (+14/−8) — подключён use work.BuildConfig.all, заведены сигналы
SPI_LO1_CE / SPI_LO1_RF_EN, и под EXTERNAL_MASTER_LO_SLAVE глушатся LO1_RF_EN,
LO1_CE, LO1_CLK, LO1_MOSI, LO1_LE; plls_locked перестаёт ждать захвата LO,
lo_unlocked фиксируется в '0'.
Все правки — под этим флагом. При false логика полностью совпадает с апстримом.
Новые файлы: BuildConfig.vhd, BuildConfig_external_lo_slave.vhd,
VNA_external_lo_slave.xise; в VNA.xise добавлена ссылка на BuildConfig.vhd.
Прочее
AssembleFirmware.py — переписан: добавлены --bitstream, --mcu, --output
(в апстриме пути зашиты жёстко). Формат выходного файла не менялся.
Пересборка
Только упаковка .vnafw — самое быстрое
cd device_firmware/reproduce
./build.sh
Берёт готовые .bin из LibreVNA/ и собирает обе прошивки в out/, затем сверяет
с эталонами. Даёт побайтовое совпадение с device_firmware/*.vnafw — проверено.
STM32 из исходников
./build.sh --stm32
или вручную:
cd LibreVNA/Software/VNA_embedded
BIN='C:/ST/STM32CubeIDE_1.17.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.12.3.rel1.win32_1.1.0.202410251130/tools/bin'
make BINPATH="$BIN" -j4 # мастер
make BINPATH="$BIN" -j4 EXTERNAL_MASTER_LO_SLAVE=1 BUILD_DIR=build_external_lo_slave
BINPATH обязателен: по умолчанию в Makefile стоит /usr/bin, под Windows это не сработает.
make.exe берите из CubeIDE (...externaltools.make.win32.../tools/bin).
FPGA — только вручную, в Xilinx ISE 14.7
ISE стоит в виртуалке VirtualBox ISE_14.7_VIRTUAL_MACHINE; её общая папка — хостовая
C:\shared, внутри гостя это /home/ise/shared.
- Скопировать
LibreVNA/FPGAвC:\shared\LibreVNA\FPGA. - В ISE открыть нужный проект:
- мастер —
/home/ise/shared/LibreVNA/FPGA/VNA/VNA.xise - slave —
.../VNA_external_lo_slave.xise
- мастер —
- Process → Generate Programming File.
- Результат —
top.bitиtop.binв каталоге проекта.
Оба проекта пишут в один и тот же top.bin, поэтому последняя сборка затирает
предыдущую — забирайте файл сразу и переименовывайте (top_master.bin /
top_external_lo_slave.bin). Именно так и потерялся исходный мастер-битстрим: slave-сборка
от 20.04 перезаписала его.
Что воспроизводится побайтово
.vnafw из готовых .bin |
да — проверено, обе прошивки совпали с device_firmware/ |
| STM32 из исходников | да — проверено, обе сборки (мастер ba729999…, slave 56654a03…) совпали побайтово на тулчейне CubeIDE 1.17.0 / gcc 12.3.1 |
| FPGA-битстрим из ISE | нет — place & route недетерминирован, плюс timestamp внутри битстрима. Логика идентична, файл будет другой |
Поэтому мастер-битстрим сохранён отдельно: extracted/master_fpga.bin и
LibreVNA/FPGA/VNA/top_master.bin. Больше нигде на машине его нет — он существовал
только внутри combined.vnafw.
Внимание: LibreVNA/FPGA/VNA/top.bin — это стоковый апстримный битстрим (тот же, что
в официальном релизе v1.6.5), а не наш мастер. Не перепутайте при упаковке.
Откуда что собрано
.vnafw |
FPGA-битстрим | STM32 |
|---|---|---|
combined.vnafw |
top_master.bin (только из этого файла) |
build/VNA_embedded.bin |
combined_external_lo_slave.vnafw |
top_external_lo_slave.bin |
build_external_lo_slave/VNA_embedded.bin |
Прошивка устройства
Штатным LibreVNA-GUI: Device → Firmware Update, скармливать .vnafw целиком —
GUI сам разложит битстрим и прошивку MCU. Отдельный master_stm32.bin нужен, только
если шить STM напрямую через ST-Link/DFU на 0x08000000.
Проверка целостности
cd device_firmware/reproduce
sha256sum -c SHA256SUMS