Skip to main content
GNSS Documentation
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Internals

Architecture Overview

┌─────────────────────────────────────────────────────┐
│                   User Application                   │
│            C++ / C / Python API Layer                │
├───────────────────┬─────────────────────────────────┤
│   IGnssHat        │   IRtk / IBase / IRover         │
│   (Navigation,    │   (RTCM3 corrections)           │
│    Timepulse,     │                                  │
│    TimeMark,      │                                  │
│    GPSD)          │                                  │
├───────────────────┴─────────────────────────────────┤
│              UBX Protocol Engine                     │
│   Parser ←→ Serializer ←→ Message Dispatcher        │
├─────────────────────────────────────────────────────┤
│              Transport Layer                          │
│   SPI Driver (TxReady IRQ)  │  UART Driver (epoll)  │
├─────────────────────────────────────────────────────┤
│              Hardware (GPIO, SPI, UART)               │
└─────────────────────────────────────────────────────┘

Threading Model

The library uses two threads:

  1. Background reader thread — reads raw bytes from SPI/UART, parses UBX messages, updates the Navigation struct
  2. User thread(s) — call waitAndGetFreshNavigation() or navigation() to read data

Synchronization:

  • Mutex protects the Navigation struct — no data races
  • Condition variable wakes blocking readers when new data arrives — no busy waiting
  • Event-driven I/O — SPI uses TxReady GPIO interrupt, UART uses Linux epoll

UBX Protocol

The library implements the u-blox UBX binary protocol (not NMEA). Key message classes:

Class ID Message Description
NAV 0x07 NAV-PVT Position, velocity, time
NAV 0x35 NAV-SAT Satellite info
NAV 0x04 NAV-DOP Dilution of precision
NAV 0x39 NAV-GEOFENCE Geofence status
MON 0x38 MON-RF RF/antenna info
TIM 0x03 TIM-TM2 Time mark
CFG Various Configuration messages

HAT Detection

At startup, the library reads /proc/device-tree/hat/product to detect which HAT is installed. Based on the product string, it instantiates the correct implementation:

Product String Implementation Transport
Contains “L1 GNSS HAT” SPI-based, NEO-M9N SPI + GPIO 17 TxReady
Contains “TIME” UART-based, NEO-F10T UART + epoll
Contains “RTK” SPI + UART, NEO-F9P SPI + UART for RTCM3

NMEA Forwarding

The GPSD forwarding creates a pseudo-terminal pair (/dev/pts/N) and optionally a symlink at /dev/jimmypaputto/gnss. A background thread converts UBX navigation data to NMEA sentences (GGA, RMC, GSA, GSV, ZDA) and writes them to the PTY slave.