portersky a1ea02771c refactor: make cel_serial_read non-blocking
Drop timeout_ms; read now returns immediately with whatever
data is available (0 if none), so callers don't block the rest
of their loop waiting on serial I/O.

telemetry's poll loop now sleeps interval_ms itself between
empty reads via a small sleep_ms helper.
2026-06-14 20:29:47 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00
2026-06-14 19:50:16 +02:00

celrs

A C23 project for interfacing with ELRS TX modules (e.g., BAYCK Nano Dual Band) via serial USB using the CRSF (Crossfire Serial) protocol.

Built on the same TDD foundation as ctdd using Unity and CMock.

All dependencies are fetched automatically via CMake FetchContent — no manual installation required beyond the tools listed below.

Requirements

Tool Purpose
CMake ≥ 3.21 Build system
Ninja Build backend
C23 compiler GCC 14+, Clang 18+
Ruby ≥ 3.0 CMock mock generation
gcovr ≥ 6.0 Coverage reports — optional (uv tool install gcovr)

Build

Configure:

cmake -S . -B build -G Ninja

Build:

ninja -C build

Test

Full Unity output with colors:

ninja -C build check

CTest summary only:

ninja -C build test

check builds all suites and runs CTest with --output-on-failure, so assertion-level detail appears on any failure without running binaries by hand.

Coverage

Configure with coverage instrumentation:

cmake -S . -B build-cov -G Ninja -DENABLE_COVERAGE=ON

Generate the HTML report:

ninja -C build-cov coverage

Open build-cov/coverage/index.html in a browser to view results.

Only celrs/ source files are measured. Unity, CMock, and generated mock files are excluded. Requires GCC or Clang with gcov support, and gcovr on PATH.

Windows note: requires GCC (e.g. scoop install gcc) or a Clang build that includes compiler-rt. A custom Clang without compiler-rt will fail at link time.

Run

Connect your ELRS TX module via USB, then run:

Windows:

./build/main.exe COM3

Linux / macOS:

./build/main /dev/ttyUSB0

Architecture

celrs/
  crsf.h / crsf.c      CRSF protocol: CRC8, frame parse/build
  serial.h / serial.c  Serial port abstraction (Win/POSIX)
  logger.h / logger.c  Level-filtering logger
  log_write.h/.c       stdout log sink
main.c                 Entry point — demo heartbeat + read
tests/
  test_crsf.c          CRSF CRC, parse, build tests
  test_serial.c        Serial open/close/stub tests
  test_logger.c        Logger level-filtering tests
deps/
  FindUnity.cmake      Fetches Unity v2.6.1 via ZIP
  FindCMock.cmake      Fetches CMock v2.6.0 via ZIP

CRSF Protocol

CRSF (Crossfire Serial Protocol) is the serial protocol used by ELRS for communication between ground station and TX/RX modules.

Frame format

+------+------+------+------+-------+-------+
| 0xC8 | dest | src  | type | size  | ...   |  CRC  |
+------+------+------+------+-------+-------+
  1 byte  1B     1B     1B     1B     N B     1 byte
  • Header: Always 0xC8
  • Destination: Target device address
  • Source: Sender device address
  • Type: Frame type (heartbeat, RC channels, telemetry, etc.)
  • Size: Payload length in bytes
  • Payload: Frame-specific data
  • CRC: CRC8-CCITT over dest+src+type+size+payload

Common device addresses

Address Device
0x00 FC Broadcast
0x10 Flight Controller
0x80 TBS Ground Station
0xEA Custom Module
0xDD RC Device

Common frame types

Type Name
0x01 RC Channels Packed
0x02 Packet Link Telemetry
0x03 Heartbeat
0x08 Device Info
0x09 Parameter List
0x17 MSP Read
0x18 MSP Write
S
Description
C23 library and CLI tools for ELRS TX modules via CRSF
Readme MIT 257 KiB
Languages
C 93.3%
CMake 6.7%