Skip to content

Build System

Complete reference for building NanoVNA-H firmware.

ToolVersionPurpose
arm-none-eabi-gcc8.x recommendedARM cross-compiler
make3.81+Build automation
dfu-util0.9+USB DFU flashing

Arch Linux:

Terminal window
sudo pacman -S arm-none-eabi-gcc arm-none-eabi-newlib dfu-util make

Ubuntu/Debian:

Terminal window
sudo apt install gcc-arm-none-eabi libnewlib-arm-none-eabi dfu-util make

macOS (Homebrew):

Terminal window
brew install --cask gcc-arm-embedded
brew install dfu-util

ChibiOS is distributed as a compressed archive, not a git submodule.

Terminal window
cd NanoVNA-H
7z x ChibiOS.7z

This creates the ChibiOS/ directory containing the RTOS source.


Terminal window
# Build for NanoVNA-H (STM32F072, default)
make
# Build for NanoVNA-H4 (STM32F303)
make TARGET=F303
# Clean build artifacts
make clean
# Flash via DFU
make flash
TargetOutputSize
F072build/H.bin~110 KB
F303build/H4.bin~130 KB

TargetDescription
allBuild firmware (default)
cleanRemove build directory
flashFlash via DFU
dfuReset device to DFU mode
TAGSGenerate etags file

# Default target
ifeq ($(TARGET),)
TARGET = F072
endif
TARGETMCUOutput
F072STM32F072xBH.bin
F303STM32F303xCH4.bin

USE_OPT = -O2 -fno-inline-small-functions -ggdb -fomit-frame-pointer \
-falign-functions=16 --specs=nano.specs -fstack-usage -std=c11
USE_OPT += -ffast-math -fsingle-precision-constant
FlagPurpose
-O2Optimization level 2
-fno-inline-small-functionsReduce code size
-ggdbDebug symbols for GDB
-fomit-frame-pointerFree up a register
-falign-functions=16Align functions for performance
--specs=nano.specsUse newlib-nano (smaller libc)
-fstack-usageGenerate stack usage reports
-std=c11C11 standard
-ffast-mathAggressive floating-point optimization
-fsingle-precision-constantUse float instead of double
USE_LTO = yes

LTO is enabled by default, allowing cross-module optimization. This reduces code size but increases build time.

USE_LINK_GC = yes

Removes unused functions and data from the final binary.


MCU = cortex-m0
UDEFS = -DARM_MATH_CM0 -DVERSION=\"$(VERSION)\"
LDSCRIPT = NANOVNA_STM32_F072/STM32F072xB.ld
  • No FPU (software floating-point)
  • Cortex-M0 instruction set
  • 128 KB flash, 16 KB RAM

# Target-specific defines
UDEFS = -DARM_MATH_CM4 -DVERSION=\"$(VERSION)\" -DNANOVNA_F303
# RTC clock source
UDEFS += -DVNA_AUTO_SELECT_RTC_SOURCE
# Or use external 32.768 kHz crystal:
# UDEFS += -DVNA_USE_LSE
# Optional features
# UDEFS += -D__VNA_Z_RENORMALIZATION__
# UDEFS += -D__VNA_FAST_LINES__

CSRC = usbcfg.c \
main.c common.c si5351.c tlv320aic3204.c \
dsp.c plot.c ui.c lcd.c \
data_storage.c hardware.c vna_math.c
CSRC += fonts/numfont16x22.c \
fonts/Font5x7.c \
fonts/Font6x10.c \
fonts/Font7x11b.c \
fonts/Font11x14.c
CSRC += FatFs/ff.c \
FatFs/ffunicode.c
CSRC = $(STARTUPSRC) \
$(KERNSRC) \
$(PORTSRC) \
$(OSALSRC) \
$(HALSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(STREAMSSRC)

# F072
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk
include $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/platform.mk
include NANOVNA_STM32_F072/board.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk
# F303
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f3xx.mk
include $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/platform.mk
include NANOVNA_STM32_F303/board.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk

# Main thread stack
USE_PROCESS_STACKSIZE = 0x200 # 512 bytes
# Exception/interrupt stack
USE_EXCEPTIONS_STACKSIZE = 0x100 # 256 bytes

VERSION = "$(shell git describe --tags)"

The version is embedded in the firmware and displayed by the version and info commands.

Example: 1.2.44


  1. Hardware: Hold BOOT0 jumper while powering on
  2. Menu: CONFIG > EXPERT SETTINGS > DFU
  3. Shell: reset dfu command
Terminal window
make flash
# Equivalent to:
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/H.bin
OptionMeaning
-d 0483:df11ST DFU device ID
-a 0Alt setting 0 (internal flash)
-s 0x08000000:leaveStart address, exit DFU after
-D build/H.binDownload this file

Terminal window
openocd -f NanoVNA_DAP.cfg

The NanoVNA_DAP.cfg file configures OpenOCD for CMSIS-DAP debugging.

Terminal window
arm-none-eabi-gdb build/H.elf
(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) load

After building, examine the output:

Terminal window
# Check binary size
arm-none-eabi-size build/H.elf
# Example output:
text data bss dec hex filename
108544 1024 8192 117760 1cc00 build/H.elf
SectionContent
textCode and constants (flash)
dataInitialized variables (flash + RAM)
bssUninitialized variables (RAM)

region `flash0' overflowed by XXXXX bytes

Solutions:

  • Disable unused features in nanovna.h
  • Reduce optimization: change -O2 to -Os
  • Remove debug commands
HardFault exception on startup

Solution: Use GCC 8.x specifically. Install from ARM’s website if your distribution has a different version.

dfu-util: No DFU capable USB device available

Solutions:

  1. Verify device is in DFU mode (BOOT0 held)
  2. Check USB connection
  3. Linux: add udev rule for DFU device
  4. Check lsusb for 0483:df11
Terminal window
make clean
rm -rf build
make TARGET=F072 # or F303

For reproducible builds with correct toolchain version:

FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
gcc-arm-none-eabi \
libnewlib-arm-none-eabi \
make \
p7zip-full
WORKDIR /build
COPY . .
RUN 7z x ChibiOS.7z && make
Terminal window
docker build -t nanovna-build .
docker run --rm -v $(pwd)/build:/build/build nanovna-build