tools/mpremote: Fix special handling of ctrl-D when host FS is mounted.
Changes are: - decision to remount local filesystem on remote device is made only if "MPY: soft reboot" is seen in the output after sending a ctrl-D - a nice message is printed to the user when the remount occurs - soft reset during raw REPL is now handled correctly Fixes issue #7731. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
203ec8ca7f
commit
fecfd52696
@ -304,8 +304,8 @@ def do_repl_main_loop(pyb, console_in, console_out_write, *, code_to_inject, fil
|
|||||||
if c == b"\x1d": # ctrl-], quit
|
if c == b"\x1d": # ctrl-], quit
|
||||||
break
|
break
|
||||||
elif c == b"\x04": # ctrl-D
|
elif c == b"\x04": # ctrl-D
|
||||||
# do a soft reset and reload the filesystem hook
|
# special handling needed for ctrl-D if filesystem is mounted
|
||||||
pyb.soft_reset_with_mount(console_out_write)
|
pyb.write_ctrl_d(console_out_write)
|
||||||
elif c == b"\x0a" and code_to_inject is not None: # ctrl-j, inject code
|
elif c == b"\x0a" and code_to_inject is not None: # ctrl-j, inject code
|
||||||
pyb.serial.write(code_to_inject)
|
pyb.serial.write(code_to_inject)
|
||||||
elif c == b"\x0b" and file_to_inject is not None: # ctrl-k, inject script
|
elif c == b"\x0b" and file_to_inject is not None: # ctrl-k, inject script
|
||||||
|
@ -621,37 +621,66 @@ class PyboardExtended(Pyboard):
|
|||||||
self.cmd = PyboardCommand(self.serial, fout, path)
|
self.cmd = PyboardCommand(self.serial, fout, path)
|
||||||
self.serial = SerialIntercept(self.serial, self.cmd)
|
self.serial = SerialIntercept(self.serial, self.cmd)
|
||||||
|
|
||||||
def soft_reset_with_mount(self, out_callback):
|
def write_ctrl_d(self, out_callback):
|
||||||
self.serial.write(b"\x04")
|
self.serial.write(b"\x04")
|
||||||
if not self.mounted:
|
if not self.mounted:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Clear flag while board reboots, it will be re-set once mounted.
|
# Read response from the device until it is quiet (with a timeout).
|
||||||
self.mounted = False
|
INITIAL_TIMEOUT = 0.5
|
||||||
|
QUIET_TIMEOUT = 0.2
|
||||||
# Wait for a response to the soft-reset command.
|
FULL_TIMEOUT = 5
|
||||||
for i in range(10):
|
t_start = t_last_activity = time.monotonic()
|
||||||
if self.serial.inWaiting():
|
data_all = b""
|
||||||
break
|
while True:
|
||||||
time.sleep(0.05)
|
t = time.monotonic()
|
||||||
|
n = self.serial.inWaiting()
|
||||||
|
if n > 0:
|
||||||
|
data = self.serial.read(n)
|
||||||
|
out_callback(data)
|
||||||
|
data_all += data
|
||||||
|
t_last_activity = t
|
||||||
|
else:
|
||||||
|
if len(data_all) == 0:
|
||||||
|
if t - t_start > INITIAL_TIMEOUT:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if t - t_start > FULL_TIMEOUT:
|
||||||
|
return
|
||||||
|
if t - t_last_activity > QUIET_TIMEOUT:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check if a soft reset occurred.
|
||||||
|
if data_all.find(b"MPY: soft reboot") == -1:
|
||||||
|
return
|
||||||
|
if data_all.endswith(b">>> "):
|
||||||
|
in_friendly_repl = True
|
||||||
|
elif data_all.endswith(b">"):
|
||||||
|
in_friendly_repl = False
|
||||||
else:
|
else:
|
||||||
# Device didn't respond so it wasn't in a state to do a soft reset.
|
|
||||||
return
|
return
|
||||||
|
|
||||||
out_callback(self.serial.read(1))
|
# Clear state while board remounts, it will be re-set once mounted.
|
||||||
|
self.mounted = False
|
||||||
self.serial = self.serial.orig_serial
|
self.serial = self.serial.orig_serial
|
||||||
n = self.serial.inWaiting()
|
|
||||||
while n > 0:
|
# Provide a message about the remount.
|
||||||
buf = self.serial.read(n)
|
out_callback(bytes(f"\r\nRemount local directory {self.cmd.root} at /remote\r\n", "utf8"))
|
||||||
out_callback(buf)
|
|
||||||
time.sleep(0.2)
|
# Enter raw REPL and re-mount the remote filesystem.
|
||||||
n = self.serial.inWaiting()
|
|
||||||
self.serial.write(b"\x01")
|
self.serial.write(b"\x01")
|
||||||
self.exec_(fs_hook_code)
|
self.exec_(fs_hook_code)
|
||||||
self.exec_("__mount()")
|
self.exec_("__mount()")
|
||||||
self.mounted = True
|
self.mounted = True
|
||||||
|
|
||||||
|
# Exit raw REPL if needed, and wait for the friendly REPL prompt.
|
||||||
|
if in_friendly_repl:
|
||||||
self.exit_raw_repl()
|
self.exit_raw_repl()
|
||||||
self.read_until(4, b">>> ")
|
prompt = b">>> "
|
||||||
|
else:
|
||||||
|
prompt = b">"
|
||||||
|
self.read_until(len(prompt), prompt)
|
||||||
|
out_callback(prompt)
|
||||||
self.serial = SerialIntercept(self.serial, self.cmd)
|
self.serial = SerialIntercept(self.serial, self.cmd)
|
||||||
|
|
||||||
def umount_local(self):
|
def umount_local(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user