tools/mpremote: Poll for friendly REPL prompt before raw mode entry.#48
Draft
andrewleech wants to merge 1 commit into
Draft
tools/mpremote: Poll for friendly REPL prompt before raw mode entry.#48andrewleech wants to merge 1 commit into
andrewleech wants to merge 1 commit into
Conversation
d640931 to
74fa650
Compare
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #48 +/- ##
========================================
Coverage 98.47% 98.48%
========================================
Files 176 176
Lines 22845 23328 +483
========================================
+ Hits 22497 22974 +477
- Misses 348 354 +6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
enter_raw_repl previously sent a single Ctrl-C, flushed the input buffer, then sent Ctrl-A and waited up to 10s for the raw REPL banner. This fails on devices that are still booting (e.g. after DTR/RTS toggling on macOS USB-serial converters resets the board on port open), or that are stuck in raw REPL, or that have a fs_hook agent stalled on a VFS read; the banner never arrives because the device is not in a state where Ctrl-A is meaningful. Add _wait_for_friendly_prompt which polls for `\r\n>>> ` with short 0.2s timeouts, alternating Ctrl-C and Ctrl-B and (after a few attempts) also sending the VFS-hook ACK byte (0x18). enter_raw_repl now confirms the device is in friendly REPL before sending Ctrl-A. Approach matches the polling pattern used successfully by mpytool to work around the same DTR/RTS reset issue on macOS, discussed in micropython#13504.
74fa650 to
4bcb03f
Compare
|
Code size report: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue micropython#13504 has been open since 2023 and affects users primarily on macOS:
mpremotefails withTransportError: could not enter raw replon the first invocation after plugging in a device. The thread has accumulated a workaround (a 2-second sleep insideenter_raw_repl), confirmations across boards and Python versions, and a comment from @pavelrevak noting hismpytooldoes not hit it because of a different polling strategy.The root cause is that opening the serial port toggles DTR/RTS on common USB-serial converters, which resets ESP32-class boards.
enter_raw_replthen sends a single Ctrl-C, flushes input, sends Ctrl-A, and blocks waiting for the raw banner. If the device is still booting, the banner never arrives and the call times out. Thetime.sleep(2)workaround works only because the device finishes booting in that window.This change replaces the single Ctrl-C + flush with
_wait_for_friendly_prompt, which polls for\r\n>>>with a 0.2s interval, alternating Ctrl-C (interrupt program) and Ctrl-B (exit raw REPL, every third attempt). After four unsuccessful attempts it also sends the VFS-hook ACK byte (0x18) to unblock a fs_hook agent stuck on a host read. Once the friendly prompt is confirmed, Ctrl-A is sent and the existing banner-read logic runs unchanged. The prompt-confirmation phase is capped atmin(3, timeout_overall), so existing callers see at most a small additional delay before the original failure mode is reported, and successful connections on already-responsive devices are not slowed.Approach is modelled on the polling pattern in
mpytoolthat @pavelrevak described in micropython#13504, adapted to mpremote's existingread_untilandserialabstractions.Testing
Not yet tested on hardware. The change needs to be validated against the macOS + ESP32 + CP2102/CP210x configuration that reproduces micropython#13504, and against a representative set of other ports (STM32, RP2, nRF) to confirm no regression in the fast path where devices respond to the first Ctrl-C. I'm planning to do this before this PR is ready for merge; flagging it now so the approach can be reviewed in parallel.
Trade-offs and Alternatives
The friendly-prompt phase adds up to 3 seconds of wall time on a device that never responds, before the same
TransportErroris raised. In practice this replaces the 10s banner-read timeout that previously fired in the same scenario, so the failure path is faster, not slower.An alternative would be to keep the current code path and add
time.sleep(2)as the issue thread suggests. That works around the macOS case but does not address devices stuck in raw REPL or with a stalled fs_hook agent, and it penalises every invocation rather than only the ones that need it.Generative AI
I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the description above.