@@ -74,6 +74,8 @@ def flush_to_msg(serial, msg):
7474 if not data .endswith (msg ):
7575 if COMMAND_LINE_FLAG :
7676 print (data )
77+ import logging
78+ logging .getLogger (__name__ ).error ("Failed to enter raw REPL. Expected %r, got %r" , msg , data )
7779 raise IOError ("Could not enter raw REPL." )
7880
7981 def flush (serial ):
@@ -84,12 +86,19 @@ def flush(serial):
8486 n = serial .inWaiting ()
8587
8688 raw_repl_msg = b"raw REPL; CTRL-B to exit\r \n >"
89+
90+ # Allow board to settle before interrupting
91+ time .sleep (0.5 )
92+
8793 # Send CTRL-B to end raw mode if required.
8894 serial .write (b"\x02 " )
89- # Send CTRL-C three times between pauses to break out of loop.
90- for i in range (3 ):
95+
96+ # Send CTRL-C 10 times with 0.1s pauses to break out of any running loop.
97+ # 0.01s is often too fast for MicroPython to register the interrupt.
98+ for i in range (10 ):
9199 serial .write (b"\r \x03 " )
92- time .sleep (0.01 )
100+ time .sleep (0.1 )
101+
93102 flush (serial )
94103 # Go into raw mode with CTRL-A.
95104 serial .write (b"\r \x01 " )
@@ -147,13 +156,23 @@ def execute(commands, serial=None, show_progress=False, callback=None):
147156 total_size = len (commands )
148157 for cnt , command in enumerate (commands ):
149158 command_bytes = command .encode ("utf-8" )
150- # Send in 256-byte chunks – no sleep needed at 115200 baud
151159 for i in range (0 , len (command_bytes ), 256 ):
152160 serial .write (command_bytes [i : min (i + 256 , len (command_bytes ))])
161+ time .sleep (0.01 )
153162 serial .write (b"\x04 " ) # Execute with CTRL-D
154- response = serial .read_until (b"\x04 >" ) # Read until prompt.
155- if len (response ) > 3 : # Check if the split is possible
156- out , err = response [2 :- 2 ].split (b"\x04 " , 1 ) # Split stdout, stderr
163+
164+ old_timeout = serial .timeout
165+ serial .timeout = max (old_timeout if old_timeout is not None else 10 , 10 )
166+ try :
167+ response = serial .read_until (b"\x04 >" ) # Read until prompt.
168+ finally :
169+ serial .timeout = old_timeout
170+
171+ if len (response ) >= 2 : # OK is 2 bytes
172+ body = response [2 :- 2 ]
173+ parts = body .split (b"\x04 " , 1 )
174+ out = parts [0 ]
175+ err = parts [1 ] if len (parts ) > 1 else b""
157176 result += out
158177 if err :
159178 return b"" , err
@@ -239,7 +258,18 @@ def rm(filename, serial=None):
239258
240259 Returns True for success or raises an IOError if there's a problem.
241260 """
242- commands = ["import os" , "os.remove('{}')" .format (filename )]
261+ script = (
262+ "import os\n "
263+ "def r(p):\n "
264+ " try:\n "
265+ " if os.stat(p)[0]&0x4000:\n "
266+ " for c in os.listdir(p): r(p.rstrip('/')+'/'+c)\n "
267+ " os.rmdir(p)\n "
268+ " else: os.remove(p)\n "
269+ " except: pass\n "
270+ "r('{}')"
271+ ).format (filename )
272+ commands = [script ]
243273 out , err = execute (commands , serial )
244274 if err :
245275 raise IOError (clean_error (err ))
@@ -320,7 +350,7 @@ def get(self, filename, target=None, serial=None):
320350 "f = open('{}', 'rb')" .format (filename ),
321351 "r = f.read" ,
322352 "result = True" ,
323- "while result:\n result = r(32 )\n if result:\n sys.stdout.buffer.write(result)\n " ,
353+ "while result:\n result = r(256 )\n if result:\n sys.stdout.buffer.write(result)\n " ,
324354 "f.close()" ,
325355 ]
326356 out , err = execute (commands , serial , True , self .on_put_update_file )
@@ -363,7 +393,7 @@ def get_by_uart(self, filename, target=None, serial=None):
363393 "f = open('{}', 'rb')" .format (filename ),
364394 "r = f.read" ,
365395 "result = True" ,
366- "while result:\n result = r(32 )\n if result:\n u.write(result)\n " ,
396+ "while result:\n result = r(256 )\n if result:\n u.write(result)\n " ,
367397 "f.close()" ,
368398 ]
369399 out , err = execute (commands , serial , True , self .on_put_update_file )
0 commit comments