diff -r 62191d1aeeed -r 701cdc76f887 eric6/MicroPython/MicroPythonCommandsInterface.py --- a/eric6/MicroPython/MicroPythonCommandsInterface.py Thu Aug 01 20:24:41 2019 +0200 +++ b/eric6/MicroPython/MicroPythonCommandsInterface.py Thu Aug 01 20:25:51 2019 +0200 @@ -138,7 +138,6 @@ return False rawReplMessage = b"raw REPL; CTRL-B to exit\r\n>" - softRebootMessage = b"soft reboot\r\n" self.__serial.write(b"\x02") # end raw mode if required self.__serial.waitForBytesWritten() @@ -151,20 +150,12 @@ self.__serial.write(b"\r\x01") # send CTRL-A to enter raw mode self.__serial.readUntil(rawReplMessage) if self.__serial.hasTimedOut(): - return False - self.__serial.write(b"\x04") # send CTRL-D to soft reset - self.__serial.readUntil(softRebootMessage) - if self.__serial.hasTimedOut(): - return False - - # some MicroPython devices seem to need to be convinced in some - # special way - data = self.__serial.readUntil(rawReplMessage) - if not data.endswith(rawReplMessage): + # it timed out; try it again and than fail self.__serial.write(b"\r\x01") # send CTRL-A again self.__serial.readUntil(rawReplMessage) if self.__serial.hasTimedOut(): return False + QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.__serial.readAll() # read all data and discard it return True @@ -199,6 +190,7 @@ result = bytearray() err = b"" + # switch on raw mode self.__blockReadyRead = True ok = self.__rawOn() if not ok: @@ -208,25 +200,38 @@ b"Could not switch to raw mode. Is the device switched on?" ) + # send commands QThread.msleep(10) for command in commands: if command: commandBytes = command.encode("utf-8") self.__serial.write(commandBytes + b"\x04") + QCoreApplication.processEvents( + QEventLoop.ExcludeUserInputEvents) + ok = self.__serial.readUntil(b"OK") + if ok != b"OK": + return ( + b"", + "Expected 'OK', got '{0}', followed by '{1}'".format( + ok, self.__serial.readAll()).encode("utf-8") + ) + # read until prompt response = self.__serial.readUntil(b"\x04>") if self.__serial.hasTimedOut(): self.__blockReadyRead = False return b"", b"Timeout while processing commands." - if b"\x04" in response[2:-2]: + if b"\x04" in response[:-2]: # split stdout, stderr - out, err = response[2:-2].split(b"\x04") + out, err = response[:-2].split(b"\x04") result += out else: err = b"invalid response received: " + response if err: self.__blockReadyRead = False return b"", err + + # switch off raw mode QThread.msleep(10) self.__rawOff() self.__blockReadyRead = False @@ -284,8 +289,9 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import os", - "print(os.listdir('{0}'))".format(dirname), + "import os as __os_", + "print(__os_.listdir('{0}'))".format(dirname), + "del __os_", ] out, err = self.execute(commands) if err: @@ -309,26 +315,34 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import os", + "import os as __os_", + "\n".join([ + "def is_visible(filename):", + " return (not filename.startswith('.') and" + " not filename.endswith('~'))", + ]), "\n".join([ "def stat(filename):", " try:", - " rstat = os.lstat(filename)", + " rstat = __os_.lstat(filename)", " except:", - " rstat = os.stat(filename)", + " rstat = __os_.stat(filename)", " return tuple(rstat)", ]), "\n".join([ "def listdir_stat(dirname):", " try:", - " files = os.listdir(dirname)", + " files = __os_.listdir(dirname)", " except OSError:", " return None", " if dirname in ('', '/'):", - " return list((f, stat(f)) for f in files)", - " return list((f, stat(dirname + '/' + f)) for f in files)", + " return list((f, stat(f)) for f in files if" + " is_visible(f))", + " return list((f, stat(dirname + '/' + f)) for f in files" + " if is_visible(f))", ]), "print(listdir_stat('{0}'))".format(dirname), + "del __os_, stat, listdir_stat", ] out, err = self.execute(commands) if err: @@ -353,8 +367,9 @@ assert dirname commands = [ - "import os", - "os.chdir('{0}')".format(dirname), + "import os as __os_", + "__os_.chdir('{0}')".format(dirname), + "del __os_", ] out, err = self.execute(commands) if err: @@ -369,14 +384,16 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import os", - "print(os.getcwd())", + "import os as __os_", + "print(__os_.getcwd())", + "del __os_", ] out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) return out.decode("utf-8").strip() - + + # TODO: test this def rm(self, filename): """ Public method to remove a file from the connected device. @@ -388,13 +405,15 @@ assert filename commands = [ - "import os", - "os.remove('{0}')".format(filename), + "import os as __os_", + "__os_.remove('{0}')".format(filename), + "del __os_", ] out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) + # TODO: test this def rmrf(self, name, recursive=False, force=False): """ Public method to remove a file or directory recursively. @@ -412,24 +431,24 @@ assert name commands = [ - "import os", + "import os as __os_", "\n".join([ "def remove_file(name, recursive=False, force=False):", " try:", - " mode = os.stat(name)[0]", + " mode = __os_.stat(name)[0]", " if mode & 0x4000 != 0:", " if recursive:", - " for file in os.listdir(name):", + " for file in __os_.listdir(name):", " success = remove_file(name + '/' + file," " recursive, force)", " if not success and not force:", " return False", - " os.rmdir(name)", + " __os_.rmdir(name)", " else:", " if not force:", " return False", " else:", - " os.remove(name)", + " __os_.remove(name)", " except:", " if not force:", " return False", @@ -437,12 +456,14 @@ ]), "print(remove_file('{0}', {1}, {2}))".format(name, recursive, force), + "del __os_, remove_file", ] out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) return ast.literal_eval(out.decode("utf-8")) + # TODO: test this def mkdir(self, dirname): """ Public method to create a new directory. @@ -454,13 +475,15 @@ assert dirname commands = [ - "import os", - "os.mkdir('{0}')".format(dirname), + "import os as __os_", + "__os_.mkdir('{0}')".format(dirname), + "del __os_", ] out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) + # TODO: test this def rmdir(self, dirname): """ Public method to remove a directory. @@ -472,13 +495,15 @@ assert dirname commands = [ - "import os", - "os.rmdir('{0}')".format(dirname), + "import os as __os_", + "__os_.rmdir('{0}')".format(dirname), + "del __os_", ] out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) + # TODO: test this def put(self, hostFileName, deviceFileName=None): """ Public method to copy a local file to the connected device. @@ -511,13 +536,17 @@ chunk = content[:64] commands.append("f(" + repr(chunk) + ")") content = content[64:] - commands.append("fd.close()") + commands.extend([ + "fd.close()", + "del f, fd", + ]) out, err = self.execute(commands) if err: raise IOError(self.__shortError(err)) return True + # TODO: test this def get(self, deviceFileName, hostFileName=None): """ Public method to copy a file from the connected device. @@ -535,29 +564,29 @@ commands = [ "\n".join([ - "try:", - " from microbit import uart as u", - "except ImportError:", + "def send_data():", " try:", - " from machine import UART", - " u = UART(0, {0})".format(115200), - " except Exception:", + " from microbit import uart as u", + " except ImportError:", " try:", - " from sys import stdout as u", + " from machine import UART", + " u = UART(0, {0})".format(115200), " except Exception:", - " raise Exception('Could not find UART module in" - " device.')", + " try:", + " from sys import stdout as u", + " except Exception:", + " raise Exception('Could not find UART module" + " in device.')", + " f = open('{0}', 'rb')".format(deviceFileName), + " r = f.read", + " result = True", + " while result:", + " result = r(32)", + " if result:", + " u.write(result)", + " f.close()", ]), - "f = open('{0}', 'rb')".format(deviceFileName), - "r = f.read", - "result = True", - "\n".join([ - "while result:", - " result = r(32)", - " if result:", - " u.write(result)", - ]), - "f.close()", + "send_data()", ] out, err = self.execute(commands) if err: @@ -582,17 +611,23 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import os", + "import os as __os_", "\n".join([ "def fsinfo():", " infolist = []", - " fsnames = os.listdir('/')", - " for fs in fsnames:", - " fs = '/' + fs", - " infolist.append((fs, os.statvfs(fs)))", + " info = __os_.statvfs('/')", + " if info[0] == 0:", + # assume it is just mount points + " fsnames = __os_.listdir('/')", + " for fs in fsnames:", + " fs = '/' + fs", + " infolist.append((fs, __os_.statvfs(fs)))", + " else:", + " infolist.append(('/', info))", " return infolist", ]), "print(fsinfo())", + "del __os_, fsinfo", ] out, err = self.execute(commands) if err: @@ -624,8 +659,9 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import os", - "print(os.uname())", + "import os as __os_", + "print(__os_.uname())", + "del __os_", ] out, err = self.execute(commands) if err: @@ -650,22 +686,23 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import sys", + "import sys as __sys_", "res = {}", # __IGNORE_WARNING_M613__ "\n".join([ "try:", - " res['name'] = sys.implementation.name", + " res['name'] = __sys_.implementation.name", "except AttributeError:", " res['name'] = 'unknown'", ]), "\n".join([ "try:", " res['version'] = '.'.join((str(i) for i in" - " sys.implementation.version))", + " __sys_.implementation.version))", "except AttributeError:", " res['version'] = 'unknown'", ]), "print(res)", + "del res, __sys_", ] out, err = self.execute(commands) if err: @@ -685,32 +722,37 @@ "def set_time(rtc_time):", " rtc = None", " try:", # Pyboard (it doesn't have machine.RTC()) - " import pyb", - " rtc = pyb.RTC()", + " import pyb as __pyb_", + " rtc = __pyb_.RTC()", " clock_time = rtc_time[:6] + (rtc_time[6] + 1, 0)", " rtc.datetime(clock_time)", - " except:", + " del __pyb_", + " except Exception:", " try:", - " import machine", - " rtc = machine.RTC()", + " import machine as __machine_", + " rtc = __machine_.RTC()", " try:", # ESP8266 may use rtc.datetime() " clock_time = rtc_time[:6] +" " (rtc_time[6] + 1, 0)", " rtc.datetime(clock_time)", - " except:", # ESP32 uses rtc.init() + " except Exception:", # ESP32 uses rtc.init() " rtc.init(rtc_time[:6])", + " del __machine_", " except:", " try:", - " import rtc, time", - " clock=rtc.RTC()", - " clock.datetime = time.struct_time(rtc_time +" - " (-1, -1))", + " import rtc as __rtc_", + " import time as __time_", + " clock=__rtc_.RTC()", + " clock.datetime = __time_.struct_time(" + "rtc_time + (-1, -1))", + " del __rtc_, __time_", " except:", " pass", ]), "set_time({0})".format((now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, - now.tm_wday)) + now.tm_wday)), + "del set_time", ] out, err = self.execute(commands) if err: @@ -725,18 +767,20 @@ @exception IOError raised to indicate an issue with the device """ commands = [ - "import time", + "import time as __time_", "\n".join([ "try:", - " print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()" - "))", + " print(__time_.strftime('%Y-%m-%d %H:%M:%S'," + " __time_.localtime()))", # __IGNORE_WARNING_M601__ "except AttributeError:", - " tm = time.localtime()", + " tm = __time_.localtime()", " print('{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'" ".format(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour," " tm.tm_min, tm.tm_sec))", + " del tm", ]), + "del __time_" ] out, err = self.execute(commands) if err: