Skip to content

serial: 1 KB receive buffers on F7 and H7 - #12001

Open
MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:feature/uart-rx-buffer
Open

MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:feature/uart-rx-buffer

Conversation

@MrScothh

@MrScothh MrScothh commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

What this fixes

A receive buffer has to hold what arrives between two runs of the task that drains it, which
for the GPS is every 20 ms. At 115200 that is 230 bytes and 256 is enough, which is why the
current size has served; at 230400 it is 460 bytes and the buffer overruns on every burst.

What that costs is not a few bytes here and there. On an H743 bench with a NEO-F10N at
230400, INAV never identified the receiver at all: packets kept arriving, more than 2800 of
them in 80 seconds, while the hardware version stayed unknown and the timeout counter climbed
to 26. UBX-MON-VER, the reply that carries it, takes 11 ms of line at that rate, so an
overrun always lands in the middle of it and the answer is lost, every five seconds, forever.
With 1 KB buffers the same receiver was identified immediately, with no timeouts and no
errors.

What I changed

The receive buffers are 1 KB on F7 and H7 and stay at 256 bytes everywhere else.

Family Ports a target defines Cost Free RAM in the maintenance build
H7 up to 8 6 KB 363 KB on the smallest target
F722 up to 6 4.5 KB 96 KB
F745 and F765 up to 8 6 KB 137 KB
F405 up to 6 - 13.7 KB, so left alone
AT32F435 up to 8 - 1.5 KB, so left alone

The note about occupied sizes being returned as uint8_t no longer held: the driver
functions and the ring indices are all 32 bit.

Testing

On a TBS Lucid H7 Wing the change adds 5376 bytes of RAM, 768 for each of the seven ports the
target defines, and the receiver at 230400 is identified in about 2 s rather than not at all.
Built for MATEKF722SE, where RAM goes from 45.7% to 47.7%, and for MATEKF405SE, which is
unchanged.

At 230400 a GPS can deliver up to 460 bytes between two runs of the task that
drains its port, and a 256 byte buffer drops whatever does not fit. On a bench
with a NEO-F10N at 230400 the receiver was never identified: its 258 byte
MON-VER reply cannot survive in a buffer smaller than itself while the regular
navigation messages keep arriving. With 1 KB buffers the same receiver was
identified immediately, with no timeouts and no errors.

The F7 and H7 have the RAM for it: 4.5 to 6 KB for all the ports a target
defines, against 96 KB free on the smallest F7 target in the maintenance build
and 363 KB on the smallest H7 one. The F405 targets have 13 to 18 KB left and
the AT32F435 targets between 1.5 and 3 KB, so they keep what they have.

The note about occupied sizes being returned as uint8_t no longer held: the
driver functions and the ring indices are all 32 bit.
@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

Increase F7/H7 UART receive buffers to 1 KB

🐞 Bug fix ✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Expands F7 and H7 UART receive buffers to prevent high-rate GPS data loss.
• Retains 256-byte buffers on memory-constrained MCU families.
• Corrects outdated documentation about serial buffer size limitations.
Diagram

graph TD
  FAMILY{"MCU family"} -->|"F7/H7"| LARGE["1 KB default"] --> UART["UART1-8 RX"] --> RING["Driver buffers"] --> GPS["GPS parser"]
  FAMILY -->|"Other MCU"| SMALL["256 B default"] --> UART
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Per-port configurable buffer sizes
  • ➕ Limits additional RAM to ports handling bursty high-rate devices.
  • ➕ Allows targets to tune buffers for their specific UART assignments.
  • ➖ Requires target-level configuration and maintenance across many boards.
  • ➖ UART roles can be reassigned at runtime, making safe defaults harder to guarantee.
2. Drain UARTs more frequently
  • ➕ Could reduce backlog without increasing static RAM usage.
  • ➖ Adds scheduler load and timing risk across targets.
  • ➖ Does not guarantee that a 258-byte reply survives competing navigation traffic.

Recommendation: Keep the family-wide compile-time default used by this PR. F7/H7 targets have sufficient RAM, and uniform 1 KB buffers protect dynamically assigned UART roles without target-specific configuration or scheduler changes.

Files changed (1) +22 / -11

Bug fix (1) +22 / -11
serial_uart.hSelect larger UART RX buffers for F7 and H7 +22/-11

Select larger UART RX buffers for F7 and H7

• Introduces a family-dependent default that assigns 1 KB receive buffers to every UART on STM32F7/H7 while retaining 256 bytes elsewhere. It also documents the high-rate GPS overflow scenario and removes the obsolete claim that occupied sizes are limited to uint8_t.

src/main/drivers/serial_uart.h

@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 add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

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