← index #18660PR #17321
Related · high · value 0.544
QUERY · ISSUE

mpremote REPL and mount issues with socket:// and RFC2217 connections

openby Josverlopened 2026-01-07updated 2026-01-07
bugtools

Port, board and/or hardware

Any platform - affects mpremote tool when connecting via socket:// or RFC2217

MicroPython version

  • mpremote 1.27.0
  • Tested against MicroPython unix port 1.27.0 via
    • socket://localhost:port
    • rfc2217://localhost:2217

Reproduction

1 unable to mount host filesystem over socket connections

  • mpremote connect socket://localhost:2218 mount .
AttributeError: 'SerialIntercept' object has no attribute 'in_waiting'

2 Incorrect newline handling in interactive repl over socket

  1. Connect to MicroPython Unix port:

    mpremote connect socket://localhost:2218 repl
    
  2. Type commands and observe output appears like:

    >>> print("hello")
                       hello
                             >>>
    

3 repl over socket://

mpremote connect socket://localhost:2218 repl

REPL may fail to respond or hang

4 repl over rfc2217

mpremote connect rfc2217://localhost:2217 repl

Output may be delayed, laggy, or appear in bursts
pyserial's RFC2217 implementation uses a background thread to process telnet data from the socket into an internal buffer. When mpremote's REPL loop uses select() on the socket, it signals "ready" when data arrives, but inWaiting() returns 0 because the background thread hasn't processed the data yet.

Race condition sequence:

  1. select() returns because socket has data
  2. inWaiting() returns 0 (background thread hasn't processed yet)
  3. REPL loop skips reading
  4. Next iteration: select() returns, now inWaiting() > 0
  5. Finally reads the data

This causes noticeable lag and stuttering in the REPL.

Expected behaviour

mpremote should work correctly with socket-based connections (socket://, RFC2217), providing:

  • Functional mount operations
  • Proper newline handling in REPL output
  • Responsive REPL without lag or race conditions

Observed behaviour

  • Mount operations fail with AttributeError
  • REPL output has "staircase" effect (misaligned lines)
  • REPL may hang or fail to get input from socket connections
  • REPL output is laggy/stuttering with RFC2217 connections

Additional Information

  • aeb1ce6 - Add in_waiting property to SerialIntercept class
  • 2d46d52 - Fix REPL newline handling
  • 7f0abfd - Improve waitchar() wrt socket connections
  • 1ff555c - Fix REPL race conditions with RFC2217

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

mpremote: Fix disconnect handling on Windows and Linux.

mergedby andrewleechopened 2025-05-19updated 2025-07-04
tools

Summary

Improves device disconnection handling in mpremote to show a clean "device disconnected" message instead of stack traces on Windows and fixes terminal formatting issues on Linux.

Problem

When a device disconnects during an mpremote session:

  • Windows: Shows a full stack trace with ClearCommError failed or similar errors
  • Linux: 'device disconnected' with unclear terminal formatting, causing indentation issues

Solution

This PR fixes disconnect handling to:

  1. Catch serial disconnection exceptions in both console.py and repl.py
  2. Properly exit terminal raw mode before showing the message
  3. Display a clean "device disconnected" message after terminal cleanup
  4. Ensure consistent behavior across Windows and Linux platforms

File Changes

tools/mpremote/mpremote/console.py:

  • Windows: Modified waitchar() to catch SerialException and re-raise with cleaner message
  • Added proper exception handling for ClearCommError failed cases

tools/mpremote/mpremote/repl.py:

  • Modified do_repl_main_loop() to catch serial exceptions and return disconnect state
  • Added checks for both Windows and Linux disconnect error patterns

tools/mpremote/mpremote/main.py:

  • Modified main loop to handle disconnect state after console cleanup
  • Added newline and message printing after terminal mode is restored

Testing

Before/After Examples - I connected to ESP32S2 (usb serial) and once confirmed the repl is working, physically unplug the devices.

Windows (Before)

PS C:\Users\anl> mpremote
Connected to MicroPython at COM7
Use Ctrl-] or Ctrl-x to exit this shell
MicroPython v1.25.0-1.ge7b0fe4775.dirty on 2025-05-09; Generic ESP32S2 module with ESP32S2
Type "help()" for more information.
>>>
>>> Traceback (most recent call last):
  File "C:\Users\anl\AppData\Roaming\uv\python\cpython-3.10.11-windows-x86_64-none\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\anl\AppData\Roaming\uv\python\cpython-3.10.11-windows-x86_64-none\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "c:\users\anl\.local\bin\mpremote.exe\__main__.py", line 8, in <module>
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\mpremote\main.py", line 584, in main
    disconnected = do_repl(state, argparse_repl().parse_args([]))
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\mpremote\repl.py", line 102, in do_repl
    disconnected = do_repl_main_loop(
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\mpremote\repl.py", line 11, in do_repl_main_loop
    console_in.waitchar(state.transport.serial)
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\mpremote\console.py", line 99, in waitchar
    while not (self.inWaiting() or pyb_serial.inWaiting()):
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\serial\serialutil.py", line 594, in inWaiting
    return self.in_waiting
  File "C:\Users\anl\AppData\Roaming\uv\tools\mpremote\lib\site-packages\serial\serialwin32.py", line 259, in in_waiting
    raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
PS C:\Users\anl>

Windows (After)

PS C:\Users\anl> mpremote
Connected to MicroPython at COM7
Use Ctrl-] or Ctrl-x to exit this shell
MicroPython v1.25.0-1.ge7b0fe4775.dirty on 2025-05-09; Generic ESP32S2 module with ESP32S2
Type "help()" for more information.
>>>
>>>
>>>
device disconnected
PS C:\Users\anl>

Linux (Before)

anl@ANL2-LAP:~/micropython/tools/mpremote$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell
MicroPython v1.25.0-1.ge7b0fe4775.dirty on 2025-05-09; Generic ESP32S2 module with ESP32S2
Type "help()" for more information.
>>>
>>> device disconnected
                       anl@ANL2-LAP:~/micropython/tools/mpremote$

Linux (After)

anl@ANL2-LAP:~/micropython/tools/mpremote$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell
MicroPython v1.25.0-1.ge7b0fe4775.dirty on 2025-05-09; Generic ESP32S2 module with ESP32S2
Type "help()" for more information.
>>>
>>>
device disconnected
anl@ANL2-LAP:~/micropython/tools/mpremote$ 
  • Tested on Windows 11 with ESP32S2 USB serial
  • Tested on Linux (Ubuntu WSL) with ESP32S2 USB serial
  • Verified terminal formatting is restored properly
  • Confirmed clean exit without stack traces

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied