Skip to content

maintenance-10.x into next-10.1 - #12207

Open
sensei-hacker wants to merge 44 commits into
next-10.1from
maintenance-10.x
Open

sensei-hacker wants to merge 44 commits into
next-10.1from
maintenance-10.x

Conversation

@sensei-hacker

Copy link
Copy Markdown
Member

No description provided.

Raphael Hunziker and others added 30 commits September 10, 2026 20:14
SBUS servo output is resolved with findSerialPortConfig(), which returns
the first port that carries FUNCTION_SERVO_SERIAL. Assigning the function
to a second port was accepted and reported back by the serial command,
but that port was never opened.

Reject such an assignment in the CLI instead of ignoring it silently.

Fixes #11430
The receiver transmit power is only written by the MSP and MAVLink RC
paths. The CRSF link statistics frame 0x14 has no such field and no
other CRSF frame is parsed for it, so with an ExpressLRS receiver the
element showed a permanent 0 mW.

ExpressLRS never sends the optional link statistics RX frame 0x1C that
would carry a power value, so parsing it would not populate the element
either. A power of 0 already means "not reported" on the other paths,
so skip drawing the element in that case.

Fixes #11136
The mixer switch carry over loop ended at the first
INPUT_MIXER_SWITCH_HELPER rule. Switching a mixer profile back before
the carry over of the previous switch had decayed therefore dropped its
remaining filter state, the newly loaded rule restarted from zero and
the servo jumped towards its mid position.

Only the carry capacity ends the loop now, helper rules are carried over
like any other speed limited rule.

Fixes #11503
The constraints list already covers the analogous telemetry rule. Adds
the SERVO_SERIAL case, including that the second assignment used to be
accepted silently without the port ever being opened.
The safehome zone appended in geoZoneInit() was counted in
activeGeoZonesCount but never had enable set, unlike the configured
zones. The following sort by enable could therefore move it behind the
counted range and pull a zeroed slot (NULL vertices) in front of it, or
keep a deliberately deactivated far inclusive zone active instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
atan2() promoted both integer arguments to double. F4/F7 have no
double-precision FPU, so this single call pulled the libgcc soft-double
arithmetic and compare routines plus the double atan/atan2 from libm into
every image. The result is truncated to integer degrees, so float
precision is more than enough.

MATEKF722 -2792 B, MATEKF405 -1460 B, MATEKF765 -1392 B, MATEKH743 -1392 B,
NEUTRONRCF435WING -1456 B flash; RAM unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A %f vararg promotes to double, which keeps libgcc's soft-double add/sub
and int-to-double routines linked on MCUs without a double FPU. The four
sites (GPS HDOP/EPH/EPV in "status", DLVR pitot debug log) only display
already scaled integers.

MATEKF722 -876 B, MATEKF765/H743/NEUTRONRCF435WING -44 B, MATEKF405 +20 B
flash; RAM unchanged. The CLI status lines now print two decimals
("1.50") instead of ftoa's " 1.500".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
newlib implements strstr and strnstr with the two-way algorithm and
memmem, about 2.8 KB of code. INAV only searches short CLI tokens,
setting names and u-blox version strings, so a plain scan is enough.
cliSet's strstr(cmdline, "=") becomes strchr. SITL's private strnstr
had no caller left and is removed.

MATEKF722 -3008 B, MATEKF405 -3232 B, MATEKF765 -2672 B, MATEKH743 -2680 B,
NEUTRONRCF435WING -2816 B flash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
These were the last callers of libm sinf/cosf/atan2f on targets without
USE_TERRAIN. sinf/cosf link the large-argument range reduction (rem_pio2
plus its 792 B table) although the arguments here never exceed 2 pi.
sin_approx/cos_approx are within 4e-7 of libm over that range and are
the codebase standard; the results feed a smoothed wind estimate and an
integer-degree telemetry value.

The tracker elevation is now rounded instead of truncated, so the
approximation's 3e-7 rad error at exact integer angles (45 deg) cannot
shift the reported value by a degree.

MATEKF722 -4808 B, MATEKF405 -4616 B, NEUTRONRCF435WING -4616 B,
MATEKF765/H743 -760 B flash; RAM unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both callers sort tiny arrays at init time: the three battery profiles by
detect voltage, and the geozone runtime list into "enabled first". An
insertion sort and a stable partition do the same and newlib's qsort
(1.6 KB) leaves the image. Enabled geozones now keep their configured
order instead of qsort's permutation; the battery order is unchanged
(newlib already insertion-sorts fewer than seven elements).

MATEKF722 -1472 B, MATEKF405 -1408 B, MATEKF765 -1288 B, MATEKH743 -1344 B,
NEUTRONRCF435WING -1408 B flash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Three byte-sized members sat between word-sized ones, costing 4 B of
padding per state in the const navFSM table. The table uses designated
initialisers, so the order change has no other effect.

MATEKF722 -196 B, the other reference targets -260 B flash.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Like the other OSD elements that hide themselves at runtime, the element
now takes its slot in the per-cycle draw budget after blanking its field.
No visible change.

The receiver transmit power is carried by CRSF frame 0x1D, not 0x1C.
INAV parses neither and ExpressLRS sends neither, so the docs no longer
claim that CRSF cannot carry the value, and name mLRS only as MAVLink
receiver.
NAV-SIG (M9, M10) and NAV-SAT (M8) were requested at every navigation
epoch. They feed only the satellite list in the CLI, yet they are most of
what the receiver sends: NAV-SIG carries 16 bytes for each tracked signal,
several hundred bytes per epoch on a multi-constellation receiver, against
about 100 for the NAV-PVT that navigation runs on.

They are now requested every (gps_ublox_nav_hz + 1) / 2 epochs, which is
about twice a second at any navigation rate.
A receive buffer has to hold what arrives between two runs of the task
that drains it. For the GPS task, 20 ms apart, that is up to 230 bytes at
115200 and 460 at 230400, and a reply to a poll has to fit whole: MON-VER
alone can be 258 bytes. With the 256 bytes every port has, a NEO-F10N at
230400 was never identified, because its MON-VER reply was always cut.

The GPS port now gets a 512 byte buffer of its own, in FASTRAM, where
there is room: CCM on F405, RAM1 on AT32F43x. serialSetRxBuffer() swaps
it in right after the port is opened. Every other port keeps its 256
bytes.

The note that occupied sizes are returned as uint8_t no longer held: the
driver functions and the ring indices are all 32 bit.
The satellite details also feed the OSD's GPS extra stats, not only
gpssats, so the comment now says both. The comments are one line each,
the buffer states the rate it covers (230400; at 460800 and above a
NAV-PVT plus a large NAV-SIG can still overflow it), its size is asserted
to be a power of two because softserial masks with size - 1, and it only
exists where the u-blox provider does, the only one that opens a port.
The note in serial_uart.h about sending a UBLOX SVINFO was stale.
Rename serialDuplicatedSinglePortFunctions() to
serialGetDuplicatedSinglePortFunctions() so the helper has a verb name
like the other serialGet*/serialFind* functions (Development.md #5).

Cut the three-line comment above SERIAL_SINGLE_PORT_FUNCTIONS to one line
that states why the list exists.

docs/Serial.md: drop the "previously it was accepted" history from the
constraint and say what happens to a saved configuration that already
has SBUS output on several ports: only the first port in the serial list
is used, the configuration is not reset.

No functional change.
Only MSP receivers that send MSP2_COMMON_SET_MSP_RC_INFO report the
receiver transmit power, and mLRS reports 0 dBm or less as 0 mW, so the
element is also hidden for mLRS at 1 mW and below. Say so in the OSD
element table.
Development.md asks for comments that explain why, not what. No
functional change.
With parity enabled the F4 data register holds the parity bit in bit 8,
and it was passed through to the rx callback. F7/H7 drivers already mask
to 8 bits. Protocol handlers comparing the received value directly, e.g.
the SBUS 0x2F start byte, never matched on F4.
… a function besides MSP

checkPwmTimerConflicts() kept outputs off the pins of UART2 to UART8 but
not UART1. On NEXUSX and VANTAC_RF007 the pads labelled AUX and SBUS are
both UART1 and two timer outputs, and SPRACINGF7DUAL has the same on PWM
3 and 4: with a receiver on UART1, a motor or servo could be assigned to
the receiver's pin and drive nothing once the receiver took it back.

UART1 gets MSP by default next to the VCP, and MSP opens before the
outputs and has always given them these pins, so MSP alone still does;
any other function on UART1 now keeps them, as on UART2 to UART8.
A reboot without a power cycle (CLI save or exit, a Configurator reboot,
a DFU flash) left the IST8310 as it was. In the continuous mode the
driver set, a value the datasheet lists as reserved, it then never
raised DRDY again: the compass kept its last reading, or zeros right
after boot, with MAG=OK in status until the next power cycle.

Following the datasheet and PX4: soft reset at init (50 ms power-on
reset), then single measurement mode, each read starting the next
measurement and restarting one that never completed. STAT1 and the data
registers come in one transfer, which cannot tear since the data only
changes after a trigger.
Beyond 1600 uT on X and Y, or 2500 uT on Z, a sample is not a field: it
can only be a corrupted transfer or a chip in a bad state, and one such
sample is enough to throw off the sphere fit of a compass calibration.
The previous sample is kept, as when no measurement is ready. ArduPilot's
IST8310 driver makes the same check.
… holds it

The fixed-wing I-term lock damps P and D and freezes the I-term while the stick asks for a big rate, so the
feed-forward flies the manoeuvre. An I-term built in a motion the pilot did not ask for is then held against the
stick and eats that feed-forward: a trainer pulling out of a spiral dive at 34 m/s got +30 us of elevator from a
demand of 111 deg/s, the I-term at +87 against a feed-forward of -115, and hit the ground level, a second short.
Now an I-term of the opposite sign to the rate target fades with a 0.5 s time constant, scaled by how far the lock
attenuates the I-term; one of the same sign, the trim the lock is meant to keep, is left alone. Same in the
auto-transition controller. Unit test on the trainer's pitch loop.
…d not on yaw

A small correction of the opposite sign to the trim would have erased it in a few seconds, and the rudder trim would
have faded in a banked turn, where the yaw rate target is the turn's. The fade now applies on roll and pitch, and
only when the rate target is above 20 % of the maximum rate, the threshold the lock itself uses to count a stick
input as big. Two unit tests.
Refuse assigning SBUS output to a second serial port
Keep the servo speed carry over when switching mixer profiles back
fw pid: an I-term that opposes a big stick input fades while the lock holds it
Flash: remove double math, newlib strstr/qsort and libm trig from the F7 images (-13 KB on F722)
@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 flight-control edge cases and reduce firmware footprint

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

Grey Divider

AI Description

• Reject duplicate SBUS assignments; preserve servo transitions and safe-home geozones.
• Fade opposing fixed-wing I-terms and add regression tests for the controller.
• Reduce firmware size with lighter string searches, sorting, math, and formatting.
Diagram

graph TD
  CLI["Serial CLI"] --> Config["Serial config"] --> SBUS["SBUS output"]
  Stick["Stick demand"] --> PID["Fixed-wing PID"] --> Servos["Servo output"]
  SafeHome["Safe-home config"] --> Zones["Runtime geozones"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Validate duplicate functions in all serial configurations
  • ➕ Would also catch duplicate assignments loaded outside the CLI.
  • ➖ Could invalidate saved configurations that currently operate using their first assigned port.
2. Retain libc and exact math implementations
  • ➕ Preserves library behavior and trigonometric precision without local replacements.
  • ➖ Retains the linked code that this maintenance work aims to remove from constrained firmware builds.

Recommendation: Keep the CLI-scoped SBUS check to prevent new ineffective assignments without rejecting existing saved configurations. The small local replacements suit the firmware-size goal, but reviewers should verify their boundary behavior and the precision trade-off of approximate trigonometry.

Files changed (21) +402 / -74

Enhancement (11) +55 / -49
string_light.cAdd compact substring searches +26/-0

Add compact substring searches

• Implements bounded and unbounded plain-scan substring searches for firmware call sites.

src/main/common/string_light.c

string_light.hExpose lightweight substring search functions +3/-0

Expose lightweight substring search functions

• Declares the new search functions and records the code-size reason for avoiding newlib's search machinery.

src/main/common/string_light.h

pitotmeter_dlvr_l10d.cRemove float formatting from pitot diagnostics +1/-1

Remove float formatting from pitot diagnostics

• Reports out-of-range pressure as an integer scaled to thousandths of an inch of water, avoiding floating-point log formatting.

src/main/drivers/pitotmeter/pitotmeter_dlvr_l10d.c

settings.cUse lightweight search for setting names +1/-1

Use lightweight search for setting names

• Switches setting-name substring matching to the local search implementation.

src/main/fc/settings.c

wind_estimator.cUse approximate trigonometry in wind estimation +3/-3

Use approximate trigonometry in wind estimation

• Replaces standard atan2, sine, and cosine calls with existing approximate math functions in the wind-estimation calculation.

src/main/flight/wind_estimator.c

gps_ublox.cUse bounded lightweight search for UBX capabilities +5/-4

Use bounded lightweight search for UBX capabilities

• Searches UBX capability fields for constellation and protocol markers with the new bounded substring function.

src/main/io/gps_ublox.c

osd.cUse approximate elevation math for telemetry +2/-2

Use approximate elevation math for telemetry

• Computes telemetry elevation with approximate atan2 and rounds the resulting angle with lrintf.

src/main/io/osd.c

navigation_private.hPack navigation FSM descriptors more tightly +4/-3

Pack navigation FSM descriptors more tightly

• Reorders descriptor fields to group word-sized members before smaller members and reduce padding in the constant state table.

src/main/navigation/navigation_private.h

battery.cStably sort battery profiles without qsort +10/-12

Stably sort battery profiles without qsort

• Uses insertion sort for the small profile array, preserving index order for equal voltage limits while avoiding the libc sort dependency.

src/main/sensors/battery.c

target.cRemove SITL-specific bounded search implementation +0/-22

Remove SITL-specific bounded search implementation

• Deletes the local strnstr implementation now that callers use the shared lightweight search function.

src/main/target/SITL/target.c

target.hRemove obsolete SITL search declaration +0/-1

Remove obsolete SITL search declaration

• Removes the declaration for the deleted SITL-specific strnstr function.

src/main/target/SITL/target.h

Bug fix (6) +67 / -25
cli.cReject duplicate SBUS assignments and lighten CLI formatting +12/-6

Reject duplicate SBUS assignments and lighten CLI formatting

• Checks single-port function conflicts before saving a serial command. Uses lighter substring and character searches and prints GPS status values with integer fixed-point formatting.

src/main/fc/cli.c

pid.cFade opposing fixed-wing I-term during large stick inputs +21/-2

Fade opposing fixed-wing I-term during large stick inputs

• Adds an attenuation-scaled fade for locked I-terms that oppose large roll or pitch rate targets in both fixed-wing controller paths. Leaves helping I-terms, small corrections, and yaw trim unaffected.

src/main/flight/pid.c

servos.cPreserve helper-rule speed limits across mixer switches +2/-2

Preserve helper-rule speed limits across mixer switches

• Continues scanning past mixer-switch helper rules when carrying over decaying speed-limit filter state. This prevents an early switch back from dropping remaining state and causing a servo jump.

src/main/flight/servos.c

serial.cDetect duplicate single-port serial functions +17/-0

Detect duplicate single-port serial functions

• Adds a helper that compares a proposed port's functions with other configured ports and reports duplicate SERVO_SERIAL assignments.

src/main/io/serial.c

serial.hDeclare duplicate serial-function check +1/-0

Declare duplicate serial-function check

• Exposes the serial configuration helper used by the CLI before accepting a port assignment.

src/main/io/serial.h

navigation_geozone.cEnable safe-home zones and stably order active zones +14/-15

Enable safe-home zones and stably order active zones

• Marks the appended nearest-safe-home zone enabled. Replaces qsort with an in-place stable partition that keeps enabled zones ahead of disabled zones without linking the sort routine.

src/main/navigation/navigation_geozone.c

Tests (3) +279 / -0
CMakeLists.txtRegister fixed-wing I-term fade unit test +5/-0

Register fixed-wing I-term fade unit test

• Adds the new test's math and filter dependencies and its PID access shim to the unit-test build.

src/test/unit/CMakeLists.txt

pid_fw_iterm_lock_fade_access.cExpose fixed-wing PID internals to tests +46/-0

Expose fixed-wing PID internals to tests

• Includes the production PID implementation in a test-only shim and provides helpers to set axis state, step the controller, and inspect its I-term and output.

src/test/unit/pid_fw_iterm_lock_fade_access.c

pid_fw_iterm_lock_fade_unittest.ccTest opposing I-term fade and trim preservation +228/-0

Test opposing I-term fade and trim preservation

• Exercises the real fixed-wing controller against an opposing-I-term scenario. Covers fade timing, helping trim, centred and small stick inputs, partial attenuation, and the yaw exclusion.

src/test/unit/pid_fw_iterm_lock_fade_unittest.cc

Documentation (1) +1 / -0
Serial.mdDocument the single-port SBUS output constraint +1/-0

Document the single-port SBUS output constraint

• Explains that the CLI refuses a second SERVO_SERIAL assignment and that existing duplicate configurations output only on the first listed port.

docs/Serial.md

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

qodo-free-for-open-source-projects Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Legacy backups lose serial settings 🔗 Cross-repo conflict ≡ Correctness
Description
cliSerial checks the entire resulting mask against the current saved configuration, so it rejects
both exported legacy duplicate SERVO_SERIAL assignments and edits to a port that already has the
function. When inav-configurator replays a backup without defaults, a rejected command leaves that
port’s function mask and baud rates unrestored; moving the function to an earlier-listed port can
also fail before a later command clears the old port.
Code

src/main/fc/cli.c[R947-950]

+    const uint32_t duplicatedFunctions = serialGetDuplicatedSinglePortFunctions(&portConfig);
+    if (duplicatedFunctions) {
+        cliPrintErrorLinef("Function %d is already assigned to another port", (int)duplicatedFunctions);
+        return;
Evidence
printSerial exports each port’s full mask in index order, including legacy duplicate
SERVO_SERIAL assignments, and configurator replays those commands individually while recording
errors and continuing. The guard compares each command with serialConfig()->portConfigs as it
exists at that moment, so it cannot account for a later line clearing the old assignment; because
portConfig starts as a copy of currentConfig, the guard also treats an existing assignment as a
conflict when only baud rates change.

inav -> inav-configurator
src/main/fc/cli.c[824-854]
src/main/fc/cli.c[947-954]
src/main/io/serial.c[316-331]
docs/Serial.md[51-51]
src/main/io/serial.c[319-331]
src/main/fc/cli.c[880-954]
External repo: iNavFlight/inav-configurator, js/backup_restore.js [187-196]
External repo: iNavFlight/inav-configurator, js/backup_restore.js [282-314]

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 `serial` CLI guard prevents some exported backups from being replayed: it rejects duplicate `SERVO_SERIAL` assignments, moves to an earlier-listed port while the old assignment still exists, and edits to a port that already has the function. Configurator continues after a rejected command, leaving that port’s mask and baud rates unrestored.
## Fix Focus Areas
- src/main/fc/cli.c[824-854]
- src/main/fc/cli.c[947-954]
- src/main/io/serial.c[319-331]
- /cross_repos/inav-configurator/js/backup_restore.js[282-314]
## Recommended Fix
Check only functions newly added by a `serial` command, using `(portConfig.functionMask & ~currentConfig->functionMask)` for the duplicate check, so edits to an existing assignment remain possible. Coordinate with inav-configurator to normalize legacy backup commands before replay: keep the SBUS bit only on the first assigned port while applying every port’s remaining mask and baud rates. Account for restores that move SBUS to an earlier-listed port before the old port is cleared; consider moving the function automatically by clearing it from the other port and printing a warning instead of rejecting the command. Verify that restoring a backup with duplicate assignments completes without a rejected `serial` command.

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



Informational

2. CLI error shows a raw bitmask, not the function number 🐞 Bug ⚙ Maintainability
Description
The rejection message prints duplicatedFunctions, which is the bitmask, so a user sees "Function
4194304". The serial command's +N/-N syntax takes the bit index (22), so the number shown
cannot be typed back to fix the problem.
Code

src/main/fc/cli.c[949]

+        cliPrintErrorLinef("Function %d is already assigned to another port", (int)duplicatedFunctions);
Evidence
FUNCTION_SERVO_SERIAL = (1 << 22). The CLI's +/- handling uses 1 << val, so users think in
bit indices.

src/main/io/serial.h[56-56]
src/main/fc/cli.c[886-897]

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 error message prints the function bitmask instead of the bit index or name.
## Fix Focus Areas
- src/main/fc/cli.c[949-949]
## Recommended Fix
Print the bit index, e.g. `__builtin_ctz(duplicatedFunctions)`, or a readable name such as "SERVO_SERIAL".

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


3. Configurator can still put SBUS output on two ports 🐞 Bug ≡ Correctness
Description
The single-port check is only called from cliSerial. The MSP serial-config handler in fc_msp.c
still writes functionMask straight from the packet, and isSerialConfigValid does not check for
this, so the Configurator Ports tab can still create the duplicate this change is meant to prevent
(#11430).
Code

src/main/io/serial.c[R319-331]

+uint32_t serialGetDuplicatedSinglePortFunctions(const serialPortConfig_t *portConfigToCheck)
+{
+    uint32_t functionMaskOfOtherPorts = 0;
+
+    for (int index = 0; index < SERIAL_PORT_COUNT; index++) {
+        const serialPortConfig_t *portConfig = &serialConfig()->portConfigs[index];
+        if (portConfig->identifier != portConfigToCheck->identifier) {
+            functionMaskOfOtherPorts |= portConfig->functionMask;
+        }
+    }
+
+    return portConfigToCheck->functionMask & functionMaskOfOtherPorts & SERIAL_SINGLE_PORT_FUNCTIONS;
+}
Evidence
grep finds serialGetDuplicatedSinglePortFunctions used only in cli.c. fc_msp.c line 3603 assigns
functionMask = sbufReadU32(src) without any check.

src/main/fc/fc_msp.c[3603-3603]
src/main/fc/cli.c[947-951]

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

## Issue description
Only the CLI rejects SBUS output on a second port. MSP writes are not checked.
## Fix Focus Areas
- src/main/fc/fc_msp.c[3603-3603]
- src/main/io/serial.c[271-331]
## Recommended Fix
Either reject or strip duplicate single-port functions in the MSP serial-config handler, or add a check to `isSerialConfigValid` so all write paths are covered.

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


Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

RAM / Flash usage vs. base commit 01a7aa3 — commit c9893bb

Using the nearest available size baseline: this build contains base commit 6cbfc64, which has no stored baseline yet, so the deltas also include what was merged to the base since 01a7aa3.

Target Flash Δ RAM Δ
MATEKF405 ⚠️ -2280 B (-0.31%) CCM: +512 B (+1.57%)
RAM: +1648 B (+1.58%)
MATEKF722 ⚠️ -8048 B (-1.67%) ITCM_RAM: -928 B (-7.40%)
RAM: +56 B (+0.06%)
TCM: +512 B (+2.02%)
MATEKF765 -1168 B (-0.15%) DTCM_RAM: +512 B (+1.79%)
SRAM1: +64 B (+0.05%)
MATEKH743 ⚠️ +4764 B (+0.60%) D2_RAM: +256 B (+7.84%)
DTCM_RAM: +512 B (+3.95%)
ITCM_RAM: -888 B (-5.41%)
RAM: +1948 B (+1.37%)

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

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Test firmware build ready — commit c9893bb

Download firmware for PR #12207

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.

sensei-hacker and others added 11 commits November 9, 2026 12:42
pwm_mapping: skip timer outputs on UART1's pins when UART1 has a function besides MSP
IST8310: fix the compass freezing after a reboot, drop impossible samples
Fix typo in flash chip management section
Fix incorrect arm result in fcSetArmState
gps: satellite details twice a second, and a 512 byte receive buffer for the GPS port
Hide the RX downlink power element when the link does not report it
F4 UART: mask received data to 8 bits, align with F7/H7
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.

7 participants