Skip to content

Refuse assigning SBUS output to a second serial port - #11912

Open
Raffi1202 wants to merge 2 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/sbus-output-second-uart
Open

Raffi1202 wants to merge 2 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/sbus-output-second-uart

Conversation

@Raffi1202

@Raffi1202 Raffi1202 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Problem

Issue #11430: the reporter set serial 0 4194304 0 0 0 0 and serial 1 4194304 0 0 0 0 to get SBUS servo output on two UARTs. serial printed both lines back as valid, but only UART1 (serial 0) ever output SBUS. Nothing told the user that the second assignment does nothing.

Cause

sbusServoInitialize() resolves the port with findSerialPortConfig(FUNCTION_SERVO_SERIAL) (src/main/io/servo_sbus.c:59), which returns the first port in ascending order that carries the function (src/main/io/serial.c:214-224). cliSerial() copies the edited port configuration without checking the other ports (src/main/fc/cli.c:932), so a second SERVO_SERIAL assignment is stored and printed but never opened.

Change

Adds serialDuplicatedSinglePortFunctions() in serial.c, which returns the bits of SERIAL_SINGLE_PORT_FUNCTIONS (currently only FUNCTION_SERVO_SERIAL) that the proposed port shares with any other port. cliSerial() calls it before applying the line and refuses with ### ERROR: Function 4194304 is already assigned to another port when the result is non-zero. Only the port being edited is compared, so removing the function from a port still works. isSerialConfigValid() and the MSP handler are unchanged, so a saved configuration with two ports is not rewritten at boot.

Test

Not run on hardware or SITL. Cause verified by reading src/main/io/servo_sbus.c:59 and src/main/io/serial.c:214-224. Upstream CI is waiting for maintainer approval: https://github.com/iNavFlight/inav/actions/runs/34513470612. No fork build exists for this branch.

Flash / RAM

Not measured yet. The upstream firmware CI has not been released for this PR, so no size report exists.

Docs

docs/Serial.md: the Constraints list now carries the SERVO_SERIAL rule, next to the analogous telemetry one, including that a second assignment used to be accepted without the port ever being opened.

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 iNavFlight#11430
@Raffi1202
Raffi1202 marked this pull request as ready for review September 11, 2026 15:45
@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

Reject duplicate SBUS output assignments in the CLI

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Reject CLI assignments placing SBUS servo output on multiple serial ports.
• Preserve existing configurations while reporting ineffective second-port assignments.
• Leave MSP and boot validation unchanged to avoid partial writes or configuration resets.
Diagram

graph TD
    A["CLI serial"] --> B["Proposed port"] --> C["Duplicate check"] --> D{"SBUS duplicate?"}
    G["Saved config"] --> C
    D -->|Yes| E["Reject assignment"]
    D -->|No| F["Apply config"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Central configuration validation
  • ➕ Rejects duplicate single-port functions regardless of configuration entry point.
  • ➕ Keeps cardinality rules in the existing global validator.
  • ➖ An invalid saved profile can trigger a disproportionate reset of all serial configuration.
  • ➖ Changes boot behavior and may silently disrupt existing profiles.
2. Transactional shared validator
  • ➕ Could enforce the same function limits across CLI, MSP, and Configurator paths.
  • ➕ Would support moving assignments without depending on packet entry order.
  • ➖ Requires staging complete MSP updates before committing them.
  • ➖ Substantially broadens scope and likely requires Configurator coordination.

Recommendation: Use the PR's narrow CLI guard for this fix because it prevents ineffective new assignments without rewriting saved profiles or risking partial MSP updates. A transactional, shared max-ports-per-function validator is the stronger long-term solution once MSP and Configurator changes can be coordinated.

Files changed (3) +26 / -0

Bug fix (3) +26 / -0
cli.cReject duplicate SBUS output before applying serial settings +6/-0

Reject duplicate SBUS output before applying serial settings

• The serial CLI checks the proposed port configuration for duplicated single-port functions. It prints an error and returns without modifying the current port when SBUS output is already assigned elsewhere.

src/main/fc/cli.c

serial.cDetect duplicated single-port serial functions +19/-0

Detect duplicated single-port serial functions

• Adds a conservative single-port function mask containing SBUS servo output. The new helper combines function masks from every other port and returns any prohibited duplicates present in the proposed configuration.

src/main/io/serial.c

serial.hExpose serial duplicate-detection helper +1/-0

Expose serial duplicate-detection helper

• Declares the duplicate single-port function checker for use by CLI configuration handling.

src/main/io/serial.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 switch off images and animations for a plain-text comment

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

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.
@sensei-hacker sensei-hacker added this to the 10.0 milestone Sep 20, 2026
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