Skip to content

blackbox: fit a ninth optional P frame field - #12126

Merged
sensei-hacker merged 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/blackbox-nine-optional-fields
Oct 26, 2026
Merged

sensei-hacker merged 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/blackbox-nine-optional-fields

Conversation

@MrScothh

@MrScothh MrScothh commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

A P frame logs up to 9 optional fields: vbat, amperage, mag x3, baro, pitot, surface and rssi. writeInterframe() collected them in int32_t deltas[8], and blackboxWriteTag8_8SVB() packs them under one 8-bit header. With all 9 present:

  • the rssi delta is written one past the end of deltas, on the stack, in every P frame;
  • its header bit is shifted out and the value is written only when it isn't zero, while decoders read a run of these fields as groups of 8 and a lone ninth as a plain signed VB that is always there. So every P frame where rssi didn't change throws the decoder off until the next I frame.

All 9 are there with VBAT, a current meter, a mag (logged by default, blackbox MAG), a baro, a pitot (virtual included), a rangefinder (MSP included) and an RSSI source. My T-28 has all of them, and its logs decode about 3 % of iterations: 172,619 frames failed in a 3 minute log. It goes back to when the pitot delta was added, so maintenance-9.x has it too.

The array now holds 9, and the writer splits a run longer than 8 into groups of 8, the way decoders read it, so a lone ninth field is a plain signed VB again. Logs with 8 or fewer of these fields are byte for byte the same, and existing decoders read the new ones without changes.

Until this is in, blackbox -MAG and save (or dropping any other of the nine) avoids it.

Testing

TBS Lucid H7 Wing on my T-28, with all nine present (VBAT, current, an IST8310 logged with blackbox MAG, a DPS310, the virtual pitot, an MSP rangefinder and RSSI), decoded with the current blackbox_decode, unchanged:

log P frames decoded iterations missing
maintenance-10.x 3 min, blackbox_rate_denom 1 3 96.9 %
this PR 40 s, blackbox_rate_denom 2 18,555 0

The header is the same in both, nine fields with this encoding. With 8 or fewer the writer goes through the same code as before, as a single group.

A new unit test checks the bytes written for 0, 1, 3, 8, 9 and 17 fields; the 9 and 17 cases fail on maintenance-10.x.

Flash: MATEKF722SE +0 B, MATEKF405SE +80 B, KAKUTEF7/KAKUTEF7HDV +64 B, MATEKH743 +96 B; ITCM unchanged on KAKUTEF7 and KAKUTEF7HDV.

Logs already recorded with all 9 fields carry no marker for whether the ninth value is there, so a decoder could only recover them by trying each P frame both ways and keeping the reading that ends on the next frame marker. I can look at that in blackbox-tools if it's useful.

A P frame logs up to 9 optional fields (vbat, amperage, mag x3, baro, pitot,
surface, rssi), but writeInterframe() collected them in an 8-entry array and
blackboxWriteTag8_8SVB() packed them under one 8-bit header. With all 9
present the ninth delta went past the end of the array on the stack, and its
header bit was shifted out, so decoders, which read runs of these fields as
groups of 8 and a lone ninth as a plain signed VB, lost sync on every P frame
where rssi did not change.

The array now holds 9, and the writer splits the fields into groups of 8 as
decoders read them. Logs with 8 or fewer of these fields are unchanged. A
unit test checks the bytes written for 0 to 17 fields.
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Fix Blackbox P-frame encoding with nine optional fields

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Expand P-frame delta storage to prevent a stack write when all nine optional fields are logged.
• Encode fields in decoder-compatible groups, preserving bytes for eight or fewer fields.
• Add byte-level tests for empty, single-field, eight-field, nine-field, and longer runs.
Diagram

graph TD
  A["Optional sensors"] --> B["P-frame deltas"] --> C{"Over eight?"} -->|Yes| D["Eight-field group"] --> E["Tail group"] --> F["Existing decoder"]
  C -->|No| G["Single group"] --> F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Special-case the ninth field in the P-frame writer
  • ➕ Limits the encoder change to the immediate nine-field case.
  • ➖ Duplicates encoding rules at the call site.
  • ➖ Does not handle longer runs through the shared encoder.

Recommendation: Keep the shared encoder's grouping approach: it matches how existing decoders read the format, retains the old output for eight or fewer fields, and handles longer runs without P-frame-specific encoding logic.

Files changed (4) +118 / -8

Bug fix (2) +18 / -8
blackbox.cAllocate space for all nine optional P-frame deltas +2/-1

Allocate space for all nine optional P-frame deltas

• Increases the shared delta buffer from eight to nine entries so logging every optional sensor field cannot write past the stack array.

src/main/blackbox/blackbox.c

blackbox_encoding.cSplit tagged signed-VB runs into decoder-compatible groups +16/-7

Split tagged signed-VB runs into decoder-compatible groups

• Moves the existing encoding into a group helper and makes the public writer process runs eight fields at a time. A lone remainder is always written as a plain signed VB, including when its value is zero.

src/main/blackbox/blackbox_encoding.c

Tests (1) +97 / -0
blackbox_encoding_unittest.ccVerify tagged signed-VB output at group boundaries +97/-0

Verify tagged signed-VB output at group boundaries

• Adds byte-level tests for zero, one, three, eight, nine, and seventeen fields. The nine-field cases verify both a zero-valued ninth field and a nonzero ninth field.

src/test/unit/blackbox_encoding_unittest.cc

Other (1) +3 / -0
CMakeLists.txtRegister Blackbox encoding unit-test dependencies +3/-0

Register Blackbox encoding unit-test dependencies

• Links the new unit test to the Blackbox and common encoding sources and enables USE_BLACKBOX for its build.

src/test/unit/CMakeLists.txt

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can route each severity your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

RAM / Flash usage vs. base commit e87050f — commit 65b3234

Using the nearest available size baseline — the PR's exact base commit has no stored baseline yet.

Target Flash Δ RAM Δ
MATEKF405 +48 B (+0.01%) CCM: ±0 B (±0.00%)
RAM: +8 B (+0.01%)
MATEKF722 +56 B (+0.01%) ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)
TCM: ±0 B (±0.00%)
MATEKF765 +200 B (+0.03%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: ±0 B (±0.00%)
MATEKH743 +128 B (+0.02%) D2_RAM: ±0 B (±0.00%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Test firmware build ready — commit 65b3234

Download firmware for PR #12126

251 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@MrScothh

MrScothh commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

Decoder side, for logs already recorded with nine fields: iNavFlight/blackbox-tools#102.

@sensei-hacker

Copy link
Copy Markdown
Member

Thanks!

@sensei-hacker
sensei-hacker merged commit 8862223 into iNavFlight:maintenance-10.x Oct 26, 2026
24 checks passed
sensei-hacker pushed a commit to iNavFlight/blackbox-log-viewer that referenced this pull request Oct 30, 2026
INAV logs up to nine optional P fields (vbat, amperage, mag x3, baro,
pitot, surface, rssi). Until iNavFlight/inav#12126 they went out as one
TAG8_8SVB group whose header byte covers only eight, the ninth written
only when non-zero; read as 8 + 1 every frame with a zero ninth value
shifts, and a T-28 log with all nine kept 1 P frame of 194,549.

For INAV logs with a run of exactly nine such fields, each P frame is
measured with the ninth value present and absent, and the reading that
ends on the next frame's marker is kept; ties are broken by how many
following frames end on markers, then by the reading the log has needed
so far, otherwise the frame is dropped. Same rules as blackbox-tools'
decoder (iNavFlight/blackbox-tools#102). Two T-28 logs now give 196,557
and 198,334 frames, every field equal to blackbox_decode; other logs
take the same path as before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants