Skip to content

refactor: simplify and reduce flash usage in osd.c and fc_msp.c via shared helpers#11573

Open
sensei-hacker wants to merge 8 commits into
iNavFlight:maintenance-10.xfrom
sensei-hacker:refactor/flash-reduction-osd-msp-switch-cases
Open

refactor: simplify and reduce flash usage in osd.c and fc_msp.c via shared helpers#11573
sensei-hacker wants to merge 8 commits into
iNavFlight:maintenance-10.xfrom
sensei-hacker:refactor/flash-reduction-osd-msp-switch-cases

Conversation

@sensei-hacker
Copy link
Copy Markdown
Member

@sensei-hacker sensei-hacker commented May 20, 2026

Summary

Reduces binary flash usage by extracting repeated code patterns in the three largest functions into shared static helpers. All changes are pure refactoring — no behavior changes, same MSP wire format. Also simplifies the source code, making it more readable.

Flash savings on MATEKF405 (STM32F405, 1MB flash, -Os + LTO):

Function Before After Delta
mspFcProcessOutCommand 17,224 B 15,924 B −1,300 B
mspFcProcessInCommand 14,172 B 13,488 B −684 B
osdDrawSingleElement 20,928 B 20,684 B −244 B
Total flash 626,784 B 625,752 B −1,032 B

Changes

osd.c

  • sprintf helpers (osdFormatIntUnit, osdWriteChar, osdWriteChar2, osdFormatTime_MMSS): replace 81 tfp_sprintf calls with lightweight helpers that skip format-string parsing — improves CPU efficiency at a small flash cost
  • Switch case consolidation: OSD_CUSTOM_ELEMENT_1..3, OSD_CUSTOM_ELEMENT_4..8, and OSD_GVAR_0..3 groups collapsed using index arithmetic (item - OSD_CUSTOM_ELEMENT_1 etc.)
  • osdDisplayBattVoltDJI: consolidates the DJI digit-count adjustment repeated verbatim across 4 battery voltage cases
  • osdFormatAngleDeg: shared angle display layout (sym + 3-digit value-or-dashes + SYM_DEGREES + NUL) used by OSD_HEADING, OSD_GROUND_COURSE, OSD_AZIMUTH
  • osdUpdateEfficiencyFilter: shared GPS-fix guard + pt1 filter update for OSD_EFFICIENCY_MAH_PER_KM and OSD_EFFICIENCY_WH_PER_KM

fc_msp.c

  • mspSerializeMotorMixer: shared serializer for both motor mixer arrays in MSP2_COMMON_MOTOR_MIXER
  • mspSerializeServoMixer: shared serializer for both servo mixer arrays in MSP2_INAV_SERVO_MIXER
  • mspDeserializeServoParams: shared deserializer for MSP_SET_SERVO_CONFIGURATION and MSP2_INAV_SET_SERVO_CONFIG
  • mspReadRates: shared rate-read loop with FD_YAW constrain, used in MSP_SET_RC_TUNING and twice in MSP2_INAV_SET_RATE_PROFILE
  • sbufWriteAxisU16 / sbufReadAxisU16: shared XYZ triplet serializers for calibration data (accZero, accGain, magZero, magGain)

Testing

  • MATEKF405 and MATEKH743 build clean with zero warnings
  • 29/29 MSP round-trip tests pass in SITL (motor mixer, calibration data, rates, attitude, status)
  • 131/131 unit tests pass including 30 new regression tests with static_assert guards on OSD enum index arithmetic

@qodo-code-review
Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Test firmware build ready — commit 8de6b22

Download firmware for PR #11573

234 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 sensei-hacker changed the title refactor: reduce flash usage in osd.c and fc_msp.c via shared helpers refactor: simplify and reduce flash usage in osd.c and fc_msp.c via shared helpers May 20, 2026
osd.c - collapse identical custom-element and GVAR switch cases:
- OSD_CUSTOM_ELEMENT_1..3: three cases -> one using item - OSD_CUSTOM_ELEMENT_1
- OSD_CUSTOM_ELEMENT_4..8: five cases -> one using item - OSD_CUSTOM_ELEMENT_4 + 3
- OSD_GVAR_0..3: four cases -> one using item - OSD_GVAR_0

fc_msp.c - extract duplicated serialization loops into static helpers:
- mspSerializeMotorMixer: shared by both loops in MSP2_COMMON_MOTOR_MIXER
- mspSerializeServoMixer: shared by both loops in MSP2_INAV_SERVO_MIXER

Flash impact on MATEKF405: mspFcProcessOutCommand -1108 bytes, net -472 bytes total.
MSP_SET_SERVO_CONFIGURATION and MSP2_INAV_SET_SERVO_CONFIG both read
the same four servo param fields (min/max/middle/rate) and call
servoComputeScalingFactors. Consolidate into a shared static helper.

Flash impact on MATEKF405: mspFcProcessInCommand -324 bytes.
osdDisplayBattVoltDJI: consolidates DJI-compat digit adjustment + voltage
display used by all four battery voltage cases (main, sag-comp, cell,
sag-comp cell).

osdFormatAngleDeg: shared buff layout (sym + 3-digit angle-or-dashes +
SYM_DEGREES + null) for OSD_HEADING, OSD_GROUND_COURSE, OSD_AZIMUTH.

osdUpdateEfficiencyFilter: shared GPS-fix guard + pt1 filter update used
by OSD_EFFICIENCY_MAH_PER_KM and OSD_EFFICIENCY_WH_PER_KM.

Flash impact on MATEKF405: osdDrawSingleElement -256 bytes, net -64 bytes
(new helpers cost 372 bytes, save 436 from the function).
sbufWriteAxisU16 / sbufReadAxisU16: replace repeated 3-axis U16
triplet reads/writes for accZero, accGain, magZero, magGain in
MSP_CALIBRATION_DATA and MSP_SET_CALIBRATION_DATA.

mspReadRates: replace the identical FD_YAW-aware rate-constrain loop
used in MSP_SET_RC_TUNING and twice in MSP2_INAV_SET_RATE_PROFILE.

Flash impact on MATEKF405:
  mspFcProcessOutCommand -192 bytes
  mspFcProcessInCommand  -360 bytes
  net total across all changes now -1032 bytes from baseline
- Remove spurious displayWrite inside drawStat_RXStats HD+CRSF block
  that caused the stat value to be written twice and row to be
  incremented twice on HD displays with CRSF (blocking regression)
- mspReadRates: widen loop variable from uint8_t to int to match
  original code and avoid signed/unsigned comparison with FD_YAW
- osdUpdateEfficiencyFilter: move GPS/speed guard fully into the
  helper and add comment clarifying the div/0 guard at call sites
- sbufWriteAxisU16: add comment explaining int16_t input / U16 wire
  format convention
osdFormatVelocityStr: collapse 3-unit × 2-_max × 4-speedType nested
switch (24 code paths, 12 tfp_sprintf call sites) into unit-symbol
selection followed by a single speedType switch (7 code paths, 4
tfp_sprintf call sites). Saves 32 B in the function, 144 B total.

mspSerializeServoParams: add output-side counterpart to the existing
mspDeserializeServoParams helper. Used in MSP_SERVO_CONFIGURATIONS and
MSP2_INAV_SERVO_CONFIG loops. LTO inlines it, so no binary size
regression; code is now symmetric on both sides of the wire.
osd.c: add explicit case OSD_UNIT_METRIC before default in
osdFormatVelocityStr unit symbol selection, making intent clear
for future enum additions.

fc_msp.c: use 0xFF instead of -1 in mspSerializeServoMixer
compat byte to make the truncation-to-255 explicit.
@sensei-hacker sensei-hacker force-pushed the refactor/flash-reduction-osd-msp-switch-cases branch from c8a2f98 to e667465 Compare May 20, 2026 20:09
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