Skip to content

fix(USBSerial): bump per-line capture buffer 128 → 512 bytes - #5307

Open
packerlschupfer wants to merge 1 commit into
prusa3d:masterfrom
packerlschupfer:pr/usbserial-bigger-linebuf
Open

fix(USBSerial): bump per-line capture buffer 128 → 512 bytes#5307
packerlschupfer wants to merge 1 commit into
prusa3d:masterfrom
packerlschupfer:pr/usbserial-bigger-linebuf

Conversation

@packerlschupfer

Copy link
Copy Markdown

Summary

USBSerial::lineBuffer is the per-line capture buffer fed to lineBufferHook callbacks (e.g. when WUI's /api/v1/log snapshots Marlin serial output). Its size was 128 bytes; any line longer than 125 chars was truncated mid-content with .. appended.

This is below several common Marlin responses:

  • M115 FIRMWARE_NAME line — concatenates FIRMWARE_NAME, version, source URL, PROTOCOL_VERSION, MACHINE_TYPE, EXTRUDER_COUNT, and UUID. ~240 chars on most printers. UUID (the last field) is silently dropped — support cases sometimes need it.
  • M503 settings dumps — many lines over 100 chars.
  • M118 user-emitted messages — no documented length cap.

Bump to 512 bytes. Trade-off is one extra ~384-byte static buffer (single global USBSerial instance) on a 196 KB-RAM xBuddy MCU. The .. truncation marker still triggers if a line exceeds the new size, so degradation is graceful — only the threshold moves up.

The truncation logic in LineBufferAppend() already uses lineBuffer.size(), so no code change there.

Test plan

  • Builds clean.
  • M115 over USB serial shows the full line (including UUID).
  • Hook callback (/api/v1/log in our fork) emits the full line without ...

Related

Hit while debugging /api/v1/log in a downstream fork — the captured M115 output was missing the UUID and Cap: lines were partially garbled. Fixing the buffer size at the root is cleaner than working around it in every hook consumer.

packerlschupfer added a commit to packerlschupfer/Prusa-Firmware-Buddy that referenced this pull request Jun 1, 2026
GCODE_LOG_LINE_LEN was capping every notify_gcode_response line at 95
chars. Long Marlin output (M115 banner, M118 echoes, multi-field state
dumps) was being silently truncated before reaching Fluidd's console.

Ring footprint grows from 16 * 96 = 1.5 KB to 16 * 256 = 4 KB static.
The per-frame WS render path already bounds payload against
MAX_FRAME_PAYLOAD, so larger entries just mean fewer per frame, not
overflow. entry.len is uint8_t and copy_len caps at GCODE_LOG_LINE_LEN-1
= 255, so the byte count still fits.

Note: this fixes the ring-buffer ceiling but does not address the
upstream USBSerial 128-byte lineBuffer cap (lib/Arduino_Core_Buddy/.../
USBSerial.cpp), which silently drops everything past 125 chars before
the next newline. The M115 FIRMWARE_NAME banner (~235 chars) is still
lost there. That cap is what pr/usbserial-bigger-linebuf (upstream PR
prusa3d#5307) raises to 512.
packerlschupfer added a commit to packerlschupfer/Prusa-Firmware-Buddy that referenced this pull request Jun 1, 2026
GCODE_LOG_LINE_LEN was capping every notify_gcode_response line at 95
chars. Long Marlin output (M115 banner, M118 echoes, multi-field state
dumps) was being silently truncated before reaching Fluidd's console.

Ring footprint grows from 16 * 96 = 1.5 KB to 16 * 256 = 4 KB static.
The per-frame WS render path already bounds payload against
MAX_FRAME_PAYLOAD, so larger entries just mean fewer per frame, not
overflow. entry.len is uint8_t and copy_len caps at GCODE_LOG_LINE_LEN-1
= 255, so the byte count still fits.

Note: this fixes the ring-buffer ceiling but does not address the
upstream USBSerial 128-byte lineBuffer cap (lib/Arduino_Core_Buddy/.../
USBSerial.cpp), which silently drops everything past 125 chars before
the next newline. The M115 FIRMWARE_NAME banner (~235 chars) is still
lost there. That cap is what pr/usbserial-bigger-linebuf (upstream PR
prusa3d#5307) raises to 512.
The USBSerial class buffers each line written to USB CDC and (when set)
hands it to a lineBufferHook callback once the newline arrives. The
buffer was 128 bytes; any line longer than 125 chars got truncated by
LineBufferAppend() with ".." appended in place of the rest, with no way
for the hook consumer to recover the rest of the line.

128 B is below several common Marlin response lines:

- M115 FIRMWARE_NAME line: ~240 chars on most printers (FIRMWARE_NAME +
  version + URL + PROTOCOL_VERSION + MACHINE_TYPE + EXTRUDER_COUNT +
  UUID, all concatenated).
- M503 settings dumps: many lines, several over 100.
- M118 user-emitted messages: no documented length cap.

The truncated output is misleading because the user can see *part* of
the answer they wanted (e.g. the FIRMWARE_NAME prefix in M115) but the
trailing bytes — including the UUID, which support cases sometimes
need — disappear.

Bump to 512 B. The ".." truncation marker still triggers for the rare
line that's longer, so the behaviour degrades gracefully; only the
threshold moves up. Static cost is one extra 384-byte buffer (single
global USBSerial instance) — negligible vs the 196 KB total RAM on the
xBuddy STM32F427.

The truncation logic itself was already parametrised on lineBuffer.size()
in USBSerial.cpp, so no code change there.
@packerlschupfer
packerlschupfer force-pushed the pr/usbserial-bigger-linebuf branch from 3904a3f to d991f57 Compare July 26, 2026 19:45
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