- C++ 70.8%
- HTML 22%
- CMake 3.2%
- Shell 2%
- Dockerfile 2%
| .devcontainer | ||
| app | ||
| deploy | ||
| docker | ||
| hw/device-tree | ||
| .gitignore | ||
| CMakeLists.txt | ||
| README.md | ||
Terrvex Core — Torizon-oriented firmware skeleton
Compact RTK-GNSS + CAN edge daemon for the Terrvex Core box (Verdin-class i.MX8 modules running Torizon OS or Debian-compatible userspace). This repository provides:
- A C++20 daemon (
terrvex-core) with an extensible sensor layer (u-blox UBX, SocketCAN + decoder registry, GPIO via libgpiod, IIO power sense stub). - Multi-stage Docker build and a host-focused docker-compose file for on-device deployment.
- A VS Code Dev Container toolchain (CMake, Boost, libgpiod, optional Docker CLI).
Architecture
- GNSS: u-blox ZED-X20D — UART reader with UBX framing (
NAV-PVT,NAV-RELPOSNEDfor heading/RTK flags). Replace stub CAN IDs / DIS scaling with values from your DIS CFM documentation. - CAN: Linux SocketCAN (
can0, optional CAN-FD). Decoders implementICandecoderand are registered incan_registry.cpp. - GPIO: libgpiod line requests for digital inputs (joystick buttons).
- Power: reads the first
in_voltage*_rawchannel under an IIO sysfs path (configureiio_device_path). - Web UI (required): Embedded HTTP server (cpp-httplib) serves a mobile-friendly dashboard + configuration forms (
app/web/index.html, Tailwind via CDN). REST:/api/v1/health,/api/v1/status,/api/v1/config(GET/POST). WebSocket:/api/v1/ws— client sends periodic ticks; each reply carries fresh telemetry JSON (terrvex.telemetry.v1). - Legacy tablet link: optional Boost.Beast WebSocket sink on
websocket_portwhen"sink": "ws"; BLE GATT and USB CDC remain stubs. - USB gadget RNDIS/ECM and Avahi (
terrvex.local) are documented underdeploy/usb-gadget/anddeploy/avahi/(host-side setup, not inside the app binary).
Prerequisites
- Docker Desktop (macOS Apple Silicon is fine; images target
linux/arm64andlinux/amd64via Debian multi-arch packages). - On the module, Torizon OS (or Debian bookworm-compatible runtime with SocketCAN +
/dev/gpiochip*+ optional IIO).
Build (container)
From the repository root:
docker build -f docker/Dockerfile -t terrvex-core:local .
The runtime stage installs Boost system/thread and libgpiod; the binary is installed to /usr/local/bin/terrvex-core.
Run on target with docker compose
-
Copy this repository (or CI artifacts) to the module.
-
Ensure CAN is up, for example:
sudo ip link set can0 up type can bitrate 500000 -
Adjust
deploy/config/config.json(UART, CAN, GPIO,web_port/web_root, optional legacy"sink": "ws"). -
From
deploy/:docker compose build docker compose up -d
The compose file uses network_mode: host, bind-mounts /dev and /run/udev, and includes device_cgroup_rules for common TTY/CAN/GPIO majors. For early bring-up you may temporarily set privileged: true on the service.
Environment overrides
TERVEX_CONFIG— JSON file path inside the container (default/etc/terrvex/config.json, bind-mounted fromdeploy/config).TERVEX_GNSS_DEVICE— prepends--gnss-deviceviadocker/entrypoint.sh.TERVEX_WEB_ROOT— overrides static UI path (default in image:/usr/share/terrvex/web).
Web UI & USB / mDNS
- Open
http://<device-ip>:8080with the defaultweb_port(orhttp://127.0.0.1:8080withnetwork_mode: hoston the module). - For Ethernet-over-USB, bring up a gadget and address (e.g. 192.168.100.1) per
deploy/usb-gadget/README.md. Setweb_portto 80 if you grantCAP_NET_BIND_SERVICEor run privileged. - For
http://terrvex.local, install Avahi on the host perdeploy/avahi/README.md.
Security: the bundled UI has no authentication; add auth/TLS before exposing on untrusted networks.
Local development (Dev Container)
Open the folder in VS Code and Reopen in Container. The dev image installs build dependencies and mounts the Docker socket so you can run docker build from inside the container.
Configure CMake (CMakeLists.txt at repo root) and build:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build
./build/app/terrvex-core --help
On macOS, SocketCAN and libgpiod are Linux-specific; use the container or a Linux VM for full linkage tests.
Configuration
- CLI: see
--help(app/src/config.cpp). - JSON: keys mirror
AppConfig(deploy/config/config.json). - RTCM serial (optional): set
rtcm_serial_enabled,rtcm_serial_device, andrtcm_serial_baudto forward RTCM from a second UART/RS232 port into the GNSS module ongnss_uart_device(TX to the receiver). Requires GNSS enabled; restart the daemon after changing serial settings.
Extending
- Add CAN decoders: implement
ICandecoder, register inregister_*functions, include incan_registry.cpp. - Drop third-party C++ under
app/third_party/and bridge fromthird_party_adapter.cpp. - Promote BLE/USB stubs by implementing
ITelemetrySinkand selectingsinkin JSON (ble/cdc).
Device tree
See hw/device-tree/README.md and the example fragment hw/device-tree/verdin-imx8mp-example.overlay.dts.
License
Proprietary / project-specific — add your SPDX identifier when you publish.