Skip to content

Release/9.1 to master - #11945

Merged
sensei-hacker merged 10 commits into
masterfrom
release/9.1
Sep 14, 2026
Merged

sensei-hacker merged 10 commits into
masterfrom
release/9.1

Conversation

@sensei-hacker

Copy link
Copy Markdown
Member

No description provided.

The size-diff bot's "RAM Δ" summed every writable memory region into one
figure, so a PR that only grew CCM (or DTCM) usage looked identical to one
that grew main RAM by the same amount - misleading on parts where those
regions have very different remaining headroom (e.g. reported +3,740 B for
MATEKF405 when the RAM region itself only grew 608 B, the rest was CCM).

extract-size-report.sh now also computes each target's per-region usage
from its .map file (matching arm-none-eabi-size -A section addresses
against the linker's own memory map, no per-family section-name table
needed) and size-diff-comment.js renders regions separately when both the
PR and baseline reports have them, falling back to the old combined figure
otherwise so existing stored baselines keep working.

Also split the shared 256 B notability threshold into separate flash
(4096 B) and RAM (1024 B, applied per-region) thresholds - the old single
threshold was too tight for flash's much larger budget and flagged nearly
every PR.
Flare only activates when a healthy rangefinder is present (see
getHwRangefinderStatus() gate in navigation.c); on GPS-only aircraft
the landing silently stays in the glide phase all the way to touchdown,
producing a consistent overshoot in height and distance that no other
autoland tuning parameter can fix. This wasn't documented anywhere users
would see it while tuning nav_fw_land_flare_alt/pitch, only in a separate
wiki-style doc, so add it to the settings descriptions directly.

Fixes #11751
Changes from Betaflight PRs #13287 and #14214:
- Add timeout handling to ReadByte() and ReadByteCrc() to prevent
  indefinite blocking during 4-way interface communication
- Update SILABS_DEVICE_MATCH to range-based detection (0xE800-0xF900)
  for broader ESC firmware compatibility
- Add ESC reboot logic in cmd_DeviceReset for Bluejay/AM32 ESCs
- Update protocol version to 108 and interface version to 20.0.06

Note: These changes could not be verified due to hardware limitations
(4-way interface did not respond on test hardware with either INAV or
Betaflight). Community testing requested.
The 4-way passthrough Connect() records the raw device signature and
detected family (SiLabs/Atmel/ARM) so ESC firmware can be identified
during passthrough, e.g. EFM8BB51x (0xE8B5) which the fixed whitelist
rejects.
Drop the unverified 4-way read timeout (Betaflight gates it behind
USE_TIMEOUT_4WAYIF, which nothing defines upstream) while keeping the
range-based SiLabs detection, reboot sequence and version bump that
actually fix EFM8BB51x detection. Also clear DEBUG_ESC slots before each
probe, record the interface mode on the STK path, and correct the
mis-attributed provenance comments.
Reverting the timed reads hoisted the parameter-loop counter back into
the esc4wayProcess loop body, colliding with the response-echo counter
of the same name in the same scope.
…jay-device-id

Fix ESC passthrough for Bluejay/AM32 ESCs (EFM8BB51x device detection)
…slope

Document rangefinder requirement for FW autoland flare phase
The addr == 0 filter meant to skip unallocated debug/symbol metadata
also caught .tcm_code, since F7/H7 place ITCM_RAM at ORIGIN 0x0 and
link that FAST_CODE section there. Detect allocation via objdump -h's
ALLOC flag instead of address, which is the only way to tell a real
zero-origin section apart from metadata that's never actually placed.

Verified against a real AOCODARCF722AIO build: the old filter silently
dropped its 11192-byte ITCM_RAM usage from the region breakdown
entirely; the fix reports it correctly alongside TCM and RAM.
…ion-reporting

Report CI size-diff RAM delta per linker region, not combined
@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

@github-actions

Copy link
Copy Markdown

Branch Targeting Suggestion

You've targeted the master branch with this PR. Please consider if a version branch might be more appropriate:

  • maintenance-9.x - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.

  • maintenance-10.x - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x

If master is the correct target for this change, no action is needed.


This is an automated suggestion to help route contributions to the appropriate branch.

@sensei-hacker
sensei-hacker merged commit e4278ef into master Sep 14, 2026
30 checks passed
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Improve linker-region size reports and ESC flashing support

✨ Enhancement 🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Reports CI RAM deltas per linker region with backward-compatible combined totals.
• Expands ESC flashing compatibility, reboot handling, and connection diagnostics.
• Documents rangefinder requirements for fixed-wing autoland flare settings.
Diagram

graph TD
  subgraph CI["CI Size Reporting"]
    Artifacts["ELF and Map"] --> Parser["Region Parser"] --> Report["Size Report"] --> Renderer["Diff Comment"]
  end
  subgraph ESC["ESC Flashing"]
    Client["ESC Tool"] --> Bridge["4-way Bridge"] --> Bootloader["ESC Bootloader"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Capture linker memory-usage output
  • ➕ Uses the linker's already-computed per-region totals
  • ➕ Avoids matching sections to address ranges after compilation
  • ➖ Requires reliably capturing interleaved build output for every target
  • ➖ Would couple report extraction more tightly to build-system invocation details
2. Parse linker maps without objdump
  • ➕ Removes an additional tool invocation
  • ➕ Uses a single artifact as the source of region and section data
  • ➖ GNU map section syntax is substantially more complex to parse
  • ➖ Distinguishing allocated runtime sections and zero-address metadata is less reliable
3. Maintain MCU-specific section mappings
  • ➕ Simple calculation for currently known targets
  • ➕ Avoids parsing linker memory configuration tables
  • ➖ Requires ongoing per-family maintenance
  • ➖ Becomes inaccurate when linker scripts rename or relocate sections

Recommendation: The PR's map-region plus objdump-section approach is the best fit: it follows each target's linker configuration, correctly handles allocated sections at address zero, and remains non-gating through graceful fallback. Capturing linker output would be viable only if the build pipeline later exposes structured per-target memory usage directly.

Files changed (10) +451 / -43

Enhancement (4) +180 / -8
compute-region-sizes.pyCompute memory usage by linker region +132/-0

Compute memory usage by linker region

• Adds a non-gating utility that parses writable regions from linker maps and allocated sections from objdump output. It assigns section sizes by runtime address and emits regional usage as JSON, falling back to an empty result on tool or parsing failures.

.github/scripts/compute-region-sizes.py

size-diff-comment.jsRender and threshold per-region RAM deltas +45/-7

Render and threshold per-region RAM deltas

• Compares and renders individual linker-region deltas when both reports support them, while preserving combined RAM fallback for older baselines. It replaces the shared noise threshold with 4096-byte flash and 1024-byte per-region RAM thresholds.

.github/scripts/size-diff-comment.js

debug.hAdd ESC debug mode identifier +1/-0

Add ESC debug mode identifier

• Extends the firmware debug mode enumeration with DEBUG_ESC for ESC connection diagnostics.

src/main/build/debug.h

cli.cExpose ESC debug mode in the CLI +2/-1

Expose ESC debug mode in the CLI

• Adds the ESC name corresponding to DEBUG_ESC so users can select the new diagnostic mode through CLI settings.

src/main/fc/cli.c

Bug fix (1) +36 / -10
serial_4way.cSupport newer ESC detection and bootloader resets +36/-10

Support newer ESC detection and bootloader resets

• Broadens SiLabs bootloader signature recognition, adds ESC signature and interface diagnostics, and increments the 4-way protocol version. Device reset commands can now pulse the selected output low for Bluejay and AM32 bootloader entry.

src/main/io/serial_4way.c

Tests (2) +200 / -15
compute-region-sizes.test.pyTest linker-region section assignment +107/-0

Test linker-region section assignment

• Adds unit coverage for RAM and CCM assignment, unmatched sections, empty regions, and allocated ITCM code at address zero. Synthetic objdump output also verifies that non-allocated metadata is excluded.

.github/scripts/compute-region-sizes.test.py

size-diff-comment.test.jsCover regional deltas and separate thresholds +93/-15

Cover regional deltas and separate thresholds

• Updates threshold expectations and adds independent flash and RAM boundary tests. New cases verify separate RAM/CCM rendering and backward-compatible combined RAM output for legacy baselines.

.github/scripts/size-diff-comment.test.js

Documentation (1) +2 / -2
Settings.mdDocument rangefinder-dependent flare behavior +2/-2

Document rangefinder-dependent flare behavior

• Clarifies that fixed-wing flare altitude and pitch settings only apply with a healthy rangefinder. It explains that GPS-only landings remain in the glide phase through touchdown.

docs/Settings.md

Other (2) +33 / -8
extract-size-report.shAdd regional usage to CI size reports +30/-5

Add regional usage to CI size reports

• Invokes the new region calculator for each ELF with a companion map file and includes non-empty region data in the generated JSON. Existing aggregate flash and RAM totals remain available when regional extraction cannot run.

.github/scripts/extract-size-report.sh

settings.yamlRegister ESC debugging and flare guidance +3/-3

Register ESC debugging and flare guidance

• Adds ESC to the generated debug-mode lookup table and updates flare setting descriptions with the rangefinder requirement. This keeps settings metadata aligned with the firmware enum and published documentation.

src/main/fc/settings.yaml

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

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. The size report never shows regions 🐞 Bug ≡ Correctness
Description
extract-size-report.sh constructs the map path as ${elf}.map, turning a discovered
<target>.elf into <target>.elf.map even though CMake 3.15 and newer emits <target>.map from
TARGET_FILE_BASE_NAME. In CI CMake/Ninja builds, the failed existence check skips regional
extraction, omits the empty regional results from the final JSON, and silently leaves every report
with the old combined RAM figure.
Code

.github/scripts/extract-size-report.sh[R73-76]

+    map="${elf}.map"
+    regions='{}'
+    if [ -f "$map" ]; then
+        regions=$(python3 "${SCRIPT_DIR}/compute-region-sizes.py" "$elf" "$map" "$SIZE_TOOL") || regions='{}'
Evidence
Firmware executables use the .elf suffix, while both firmware CMake implementations use
TARGET_FILE_BASE_NAME, which strips that suffix before appending .map on CMake 3.15 and newer.
The extraction code instead appends .map to the full ELF path, so CI cannot find the generated map
after its CMake/Ninja builds; regional extraction is skipped, and the empty regional results are
omitted from the final JSON.

.github/scripts/extract-size-report.sh[73-76]
cmake/arm-none-eabi.cmake[8-22]
cmake/stm32.cmake[215-222]
cmake/at32.cmake[207-214]
cmake/main.cmake[74-85]
cmake/stm32.cmake[215-221]
cmake/stm32.cmake[245-246]
cmake/at32.cmake[207-213]
.github/workflows/ci.yml[122-125]
.github/scripts/extract-size-report.sh[84-90]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The extraction script searches for `<target>.elf.map`, while current CMake firmware builds generate `<target>.map`. This prevents per-region size computation in CI and silently leaves reports with the old combined RAM totals.

## Fix Focus Areas
- .github/scripts/extract-size-report.sh[68-76]
- cmake/stm32.cmake[215-221]
- cmake/at32.cmake[207-213]

## Recommended Fix
Derive the primary map path by replacing the ELF file's `.elf` suffix with `.map` while preserving its containing directory, for example with `${elf%.elf}.map`. To retain compatibility with repository builds using CMake versions older than 3.15, check the legacy `${elf}.map` path if the primary path does not exist. Add an integration-level test or fixture verifying that a map generated beside `target.elf` as `target.map` is discovered.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Changed memory layouts show false deltas 🐞 Bug ≡ Correctness
Description
diffSizeReports unions both region-name sets and substitutes zero for any region absent from one
report, despite identifying that situation as incomparable. When a target gains, loses, or renames a
linker region, reviewers see its entire usage reported as growth or shrinkage and the synthetic
change can also trigger the warning marker.
Code

.github/scripts/size-diff-comment.js[R64-67]

+            const names = Array.from(new Set([...Object.keys(pr.regions), ...Object.keys(base.regions)])).sort();
+            regionDeltas = names.map((name) => {
+                const prBytes = pr.regions[name] || 0;
+                const baseBytes = base.regions[name] || 0;
Evidence
The implementation's comment explicitly says a region missing on one side would yield a misleading
partial comparison, but the following code unions the names and converts each missing value to zero.
The renderer displays every resulting regional delta and uses those same synthetic deltas for
notability.

.github/scripts/size-diff-comment.js[58-69]
.github/scripts/size-diff-comment.js[72-74]
.github/scripts/size-diff-comment.js[124-131]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Regional comparison treats a missing region as zero usage, creating false deltas when linker-region names differ between the PR and baseline.

## Fix Focus Areas
- .github/scripts/size-diff-comment.js[58-74]
- .github/scripts/size-diff-comment.test.js[419-435]

## Recommended Fix
Only construct `regionDeltas` when both reports contain identical region-name sets. If either breakdown is absent or their key sets differ, leave `regionDeltas` undefined so rendering and notability checks fall back to the combined RAM delta; add tests covering added, removed, and renamed regions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: 🧠 Deep: This PR combines substantial new CI/reporting logic with multiple firmware behavior changes across independent code paths, including ESC detection, bootloader reset timing, debug interfaces, and protocol updates, creating a dense set of easy-to-miss defects.

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +64 to +67
const names = Array.from(new Set([...Object.keys(pr.regions), ...Object.keys(base.regions)])).sort();
regionDeltas = names.map((name) => {
const prBytes = pr.regions[name] || 0;
const baseBytes = base.regions[name] || 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Changed memory layouts show false deltas 🐞 Bug ≡ Correctness

diffSizeReports unions both region-name sets and substitutes zero for any region absent from one
report, despite identifying that situation as incomparable. When a target gains, loses, or renames a
linker region, reviewers see its entire usage reported as growth or shrinkage and the synthetic
change can also trigger the warning marker.
Agent Prompt
## Issue description
Regional comparison treats a missing region as zero usage, creating false deltas when linker-region names differ between the PR and baseline.

## Fix Focus Areas
- .github/scripts/size-diff-comment.js[58-74]
- .github/scripts/size-diff-comment.test.js[419-435]

## Recommended Fix
Only construct `regionDeltas` when both reports contain identical region-name sets. If either breakdown is absent or their key sets differ, leave `regionDeltas` undefined so rendering and notability checks fall back to the combined RAM delta; add tests covering added, removed, and renamed regions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +73 to +76
map="${elf}.map"
regions='{}'
if [ -f "$map" ]; then
regions=$(python3 "${SCRIPT_DIR}/compute-region-sizes.py" "$elf" "$map" "$SIZE_TOOL") || regions='{}'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. The size report never shows regions 🐞 Bug ≡ Correctness

extract-size-report.sh constructs the map path as ${elf}.map, turning a discovered
<target>.elf into <target>.elf.map even though CMake 3.15 and newer emits <target>.map from
TARGET_FILE_BASE_NAME. In CI CMake/Ninja builds, the failed existence check skips regional
extraction, omits the empty regional results from the final JSON, and silently leaves every report
with the old combined RAM figure.
Agent Prompt
## Issue description
The extraction script searches for `<target>.elf.map`, while current CMake firmware builds generate `<target>.map`. This prevents per-region size computation in CI and silently leaves reports with the old combined RAM totals.

## Fix Focus Areas
- .github/scripts/extract-size-report.sh[68-76]
- cmake/stm32.cmake[215-221]
- cmake/at32.cmake[207-213]

## Recommended Fix
Derive the primary map path by replacing the ELF file's `.elf` suffix with `.map` while preserving its containing directory, for example with `${elf%.elf}.map`. To retain compatibility with repository builds using CMake versions older than 3.15, check the legacy `${elf}.map` path if the primary path does not exist. Add an integration-level test or fixture verifying that a map generated beside `target.elf` as `target.map` is discovered.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@github-actions

Copy link
Copy Markdown

RAM / Flash usage vs. base commit 999ae03 — commit d5c29d6

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

Target Flash Δ RAM Δ
MATEKF405 ±0 B (±0.00%) ±0 B (±0.00%)
MATEKF722 ±0 B (±0.00%) ±0 B (±0.00%)
MATEKF765 ±0 B (±0.00%) ±0 B (±0.00%)
MATEKH743 ±0 B (±0.00%) ±0 B (±0.00%)

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

@github-actions

Copy link
Copy Markdown

Test firmware build ready — commit d5c29d6

Download firmware for PR #11945

245 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.

@sensei-hacker

Copy link
Copy Markdown
Member Author

Followed up on Qodo's two findings here directly on release/9.1 (where this feature actually lives) rather than on this sync PR: #11948

  • "Changed memory layouts show false deltas" (size-diff-comment.js): confirmed real, reproduced, and fixed in Fix spurious per-region size deltas when a target's regions are renamed #11948 - a target whose region names change between commits (rename/split with zero real growth) was showing large fictitious per-region gains/losses and could get flagged notable. Now falls back to the combined RAM delta (with a note that the layout changed) when the two sides' region sets don't match exactly.
  • "The size report never shows regions" (extract-size-report.sh map-path suffix): checked against this project's actual cmake — stm32.cmake/at32.cmake define the executable target itself as ${args_NAME}.elf (.elf is part of the CMake target name, not a build-system-imposed suffix CMake would strip), so TARGET_FILE_BASE_NAME returns it unchanged regardless of CMake version, and the map file is <target>.elf.map either way. Verified against real build artifacts. Not an actual issue for this codebase, so no change made for it.

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.

1 participant