Lab Notes

Various personal weekend projects

Mar 24, 2024

ADS-B on a Rock64 with FreeBSD stable/14

I previously ran NetBSD 10_RC for several months on my Rock64 device. I was able to get the FlightAware version of dump1090 (aka dump1090-fa) to work reasonably well (but usually had a core dump on shutdown). Unfortunately, the full suite of rtl-sdr tools, as well as rtl_433, didn't work well at all. I have details about this experiement at Experimenting with RTL-SDR on NetBSD 10.

FreeBSD has better USB support for RTL-SDR devices and there are images available for the Rock64. I decided to switch to FreeBSD to run dump1090 and rtl_433. These are my notes.

Booting FreeBSD 14 from eMMC storage

You can download a FreeBSD 14 stable image and prepare an SD card to boot. Unfortunately, the kernel provided in the image does not support booting from eMMC. I decided to build a custom FreeBSD stable/14 kernel to add eMMC support.

The FreeBSD arm64 wiki has details on building a custom kernel. I created a custom kernel config at /usr/src/sys/arm64/conf/ROCK64 which includes support for booting from an eMMC card:

include ROCKCHIP
ident   ROCK64

# pass(4) device
device                pass
options               MMCCAM
nodevice      mmc
nodevice      mmcsd

After checking out and pulling stable/14 (git checkout stable/14 ; git pull) in /usr/src I was ready to build a new kernel:

make buildkernel TARGET=arm64 KERNCONF=ROCK64

While that was building, I prepared the eMMC with the Rock64 image and mounted to /mnt:

dd if=FreeBSD-14.0-STABLE-arm64-aarch64-ROCK64-20240314-91c1c36102a6-266971.img of=/dev/da2 bs=1m status=progress
mount /dev/da1p2 /mnt

Once the kernel was built, I installed to the mounted image:

make installkernel TARGET=arm64 KERNCONF=ROCK64 DESTDIR=/mnt

That installs the kernel as well as flattened device tree files. At the time, it looked like the FreeBSD FlattenedDeviceTree page wasn't up to date. To ensure my custom kernel had the correct Rock64 DTB file I explicitely loaded it in /boot/loader.conf:

rk3328-rock64.dtb_type="dtb"
rk3328-rock64.dtb_name="/boot/dtb/rockchip/rk3328-rock64.dtb"
rk3328-rock64.dtb_load="YES"

I then unmounted the eMCC and successfully booted FreeBSD stable/14 from an eMMC card on my Rock64. Two RTL-SDR USB devices were successfully found attached to the USB 3 port (using a powered USB 3 hub):

ugen2.6: <Generic RTL2832U> at usbus2
ugen2.7: <Realtek RTL2832U> at usbus2

Running dump1090-fa

To compile dump1090-fa you need cmake and pkgconf packages, and need to modify the Makefile. Here's the git diff:

diff --git a/Makefile b/Makefile
index abe5b06..b85e4bd 100644
--- a/Makefile
+++ b/Makefile
@@ -3,8 +3,8 @@ PROGNAME=dump1090
 DUMP1090_VERSION ?= unknown

 CFLAGS ?= -O3 -g
-DUMP1090_CFLAGS := -std=c11 -fno-common -Wall -Wmissing-declarations -Werror -Wformat-signedness -W
-DUMP1090_CPPFLAGS := -I. -D_POSIX_C_SOURCE=200112L -DMODES_DUMP1090_VERSION=\"$(DUMP1090_VERSION)\" -DMODES_DUMP1090_VARIANT=\"dump1090-fa\"
+DUMP1090_CFLAGS := -std=c11 -fno-common -Wall -Wmissing-declarations -W
+DUMP1090_CPPFLAGS := -I. -D_POSIX_C_SOURCE=200112L -DMODES_DUMP1090_VERSION=\"$(DUMP1090_VERSION)\" -DMODES_DUMP1090_VARIANT=\"dump1090-fa\" -DM_PI=3.14159265358979323846 -DM_SQRT2=1.41421356237309504880

 LIBS = -lpthread -lm
 SDR_OBJ = cpu.o sdr.o fifo.o sdr_ifile.o dsp/helpers/tables.o

The main issue is lack of M_PI, etc, constants. I was able to solve this without declaring macros in NetBSD but couldn't for FreeBSD. Once built, I created an RC file /usr/local/etc/rc.d/dump1090:

#!/bin/sh

# PROVIDE: dump1090
# REQUIRE: DAEMON NETWORKING
# KEYWORD: shutdown

#
# Add the following lines to /etc/rc.conf.local, /etc/rc.conf or
# /etc/rc.conf.d/dump1090 to enable this service:
#
# dump1090_enable (bool):       Set to NO by default.
#                               Set it to "YES" to enable dump1090.
# dump1090_device (str):        Set to 0 by default.
#                               RTL-SDR device index.

. /etc/rc.subr

name=dump1090
rcvar=dump1090_enable

load_rc_config $name

: ${dump1090_enable:="NO"}
: ${dump1090_device:="0"}
: ${dump1090_gain:="20"}

NET_OPTIONS="--net-heartbeat 60 --net-ro-size 1300 --net-ro-interval 0.2 --net-ri-port 0 --net-ro-port 30002 --net-sbs-port 30003 --net-bi-port 30004,30104 --net-bo-port 30005"

pidfile="/var/run/${name}.pid"
procname="/lab/dump1090/${name}"
command="/usr/sbin/daemon"
command_args="-S -m 3 -s info -l daemon --syslog-tag ${name} -p ${pidfile} ${procname} --quiet --device-index ${dump1090_device} --gain ${dump1090_gain} ${NET_OPTIONS}"

run_rc_command "$1"

And settings in /etc/rc.conf:

dump1090_enable="YES"
dump1090_device="1"
dump1090_gain="20"

I was then able to remotely connect my PiAware Docker container to dump1090 running on my Rock64. The reason I do this is the Rock64 is in outside weatherproof enclosure close to my 1090MHz and 433MHz antennas. I have a good ethernet connection from the Rock64 to my Docker server.

Running rtl_433

FreeBSD has a package for rtl-433, so I had no issues running this on my other RTL-SDR USB receiver. If I run rtl_test this is device 0, and the ADS-B one is device 1. I have to specify this in both configurations. For example, here are the relevent lines in /usr/local/etc/rtl_433.conf:

## Tuner options
# as command line option:
#   [-d <RTL-SDR USB device index>] (default: 0)
#   [-d :<RTL-SDR USB device serial (can be set with rtl_eeprom -s)>]
#   [-d "" Open default SoapySDR device
#   [-d driver=rtlsdr Open e.g. specific SoapySDR device
# default is "0" (RTL-SDR) or "" (SoapySDR)
device        0

I have several 433MHz temperature and humidity sensors and I use rtl_433 to publish to my Mosquitto MQTT broker, with of course the obligatory Home Assistant integration.

Summary

The Rock64 runs FreeBSD 14 well and I've been using it as both an ADS-B and rtl_433 receiver for several weeks now. I'm more comfortable with NetBSD's build.sh, but building a custom FreeBSD stable/14 kernel was straight forward.

I also have a RockPro64 device and I'll keep NetBSD 10 on that -- runs really well.

Overall, a fun project and the Rock64 is a fun little device.