Logger writes to stderr so it doesn't corrupt the dashboard on stdout. Dashboard tracks its own line count and uses cursor-up instead of home so log messages appear cleanly before/after instead of interleaved.
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.
Architecture
celrs/
crsf.h / crsf.c CRSF protocol: CRC8/DVB-S2, frame build/parse
crsf_telemetry.h/.c Telemetry frame decoders (GPS, battery, link..)
crsf_stream.h/.c Incremental streaming frame reader
crsf_param.h/.c Parameter protocol (read/write/set_power)
serial.h / serial.c Serial port abstraction (Win/POSIX)
logger.h / logger.c Level-filtering logger
log_write.h/.c stdout log sink
tools/
telemetry.c Telemetry read tool
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 (ELRS USB CRSF)
+--------+----------+--------+----------+-----+
| addr | length | type | payload | CRC |
+--------+----------+--------+----------+-----+
1 byte 1 byte 1 byte N bytes 1B
- Address: Frame sync byte (
0xC8for host,0xEEfor module, etc.) - Length: Total bytes after this field (type + payload + CRC)
- Type: Frame type (RC channels, telemetry, parameter, etc.)
- Payload: Frame-specific data
- CRC: CRC8/DVB-S2 (poly
0xD5) over type + payload
Common device addresses
| Address | Device |
|---|---|
| 0x00 | FC Broadcast |
| 0x10 | Flight Controller |
| 0x80 | TBS Ground Station |
| 0xEA | Custom Module (Radio) |
| 0xEE | ELRS TX Module |
| 0xEF | ELRS Lua (host script) |
Common frame types
| Type | Name |
|---|---|
| 0x01 | RC Channels Packed |
| 0x02 | GPS |
| 0x08 | Battery |
| 0x0B | Heartbeat |
| 0x14 | Link Stats |
| 0x16 | RC Channels |
| 0x28 | Device Ping |
| 0x29 | Device Info |
| 0x2B | Parameter Entry |
| 0x2C | Parameter Read |
| 0x2D | Parameter Write |
| 0x2E | ELRS Status |