Implement bfebbx: Betaflight blackbox extractor
Cross-platform (macOS + Linux) C++17 CLI that extracts a Betaflight FC's blackbox log in one command: auto-detect the serial port, read craft_name over the Betaflight CLI, send `msc` to reboot into USB mass storage, wait for the volume to mount, copy btfl_all.bbl to <craft_name>_<YYYYMMDD>_<HHMMSS>.bbl, and eject. Native throughout (termios serial, getmntinfo/proc-mounts mount detection, DiskArbitration/umount eject); the only subprocess is the Linux udisksctl eject fallback. Includes CMake/ctest build, unit tests for the pure logic (naming, craft_name parsing, mount diff, serial via pty, CLI parsing), README with a manual hardware integration procedure, and design/plan docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
78
README.md
Normal file
78
README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# bfebbx — Betaflight Extract Blackbox
|
||||
|
||||
Extract a Betaflight flight controller's blackbox log to a timestamped,
|
||||
craft-named file in a single command. macOS and Linux.
|
||||
|
||||
## What it does
|
||||
|
||||
1. Auto-detects the FC's serial port.
|
||||
2. Reads `craft_name` over the Betaflight CLI.
|
||||
3. Sends `msc` to reboot the FC into USB mass-storage mode.
|
||||
4. Waits for the storage volume to mount, then copies `btfl_all.bbl` to
|
||||
`<craft_name>_<YYYYMMDD>_<HHMMSS>.bbl`.
|
||||
5. Ejects the volume.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
cmake -S . -B build
|
||||
cmake --build build
|
||||
ctest --test-dir build # run unit tests
|
||||
```
|
||||
|
||||
The binary is `build/bfebbx`.
|
||||
|
||||
Requirements: a C++17 compiler and CMake ≥ 3.16. No third-party libraries.
|
||||
macOS links the system DiskArbitration/CoreFoundation frameworks.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
bfebbx [--port PORT] [--output DIR] [--craft-name NAME] [--timeout SEC] [-v]
|
||||
```
|
||||
|
||||
| Flag | Default | Meaning |
|
||||
|------|---------|---------|
|
||||
| `--port` | auto-detect | Serial device (e.g. `/dev/tty.usbmodem1101`). |
|
||||
| `--output` | current dir | Directory for the extracted `.bbl`. |
|
||||
| `--craft-name` | read from FC | Override / fallback craft name. |
|
||||
| `--timeout` | 30 | Seconds to wait for the storage volume. |
|
||||
| `-v` | off | Verbose progress on stderr. |
|
||||
|
||||
### Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| 0 | Success |
|
||||
| 2 | No candidate serial port |
|
||||
| 3 | Multiple candidate ports (pass `--port`) |
|
||||
| 4 | Serial open / handshake failure |
|
||||
| 5 | Storage volume did not appear before timeout |
|
||||
| 6 | `btfl_all.bbl` not found on the volume |
|
||||
| 7 | Copy failed |
|
||||
| 8 | Destination file already exists |
|
||||
| 64 | Usage error |
|
||||
|
||||
## Manual integration test (requires a real FC)
|
||||
|
||||
The pure logic is unit-tested. The serial handshake and eject need hardware:
|
||||
|
||||
1. Flash/confirm a Betaflight FC with blackbox logs on onboard flash.
|
||||
2. Connect it via USB. Confirm the port appears: `ls /dev/tty.usbmodem*`
|
||||
(macOS) or `ls /dev/ttyACM*` (Linux).
|
||||
3. Run `./build/bfebbx -v` in an empty directory.
|
||||
4. Verify:
|
||||
- The craft name is read and printed.
|
||||
- The FC re-enumerates as a USB drive.
|
||||
- A file `<craft_name>_<date>_<time>.bbl` is written and matches the size
|
||||
of `btfl_all.bbl` on the drive.
|
||||
- The volume is ejected (no longer in `/Volumes` on macOS / `/proc/mounts`
|
||||
on Linux).
|
||||
5. Re-run in the same directory within the same second is not required; the
|
||||
timestamp differs each run, so collisions are not expected. To exercise the
|
||||
overwrite guard, `--craft-name X` twice within one second and confirm exit
|
||||
code 8.
|
||||
|
||||
## Design
|
||||
|
||||
See `docs/superpowers/specs/2026-07-22-bfebbx-design.md`.
|
||||
Reference in New Issue
Block a user