Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On Windows (and Linux?) rshell is significantly slower when -p is specified #202

Open
arbego opened this issue Nov 8, 2022 · 2 comments

Comments

@arbego
Copy link

arbego commented Nov 8, 2022

In PowerShell:

Without -p option: 0.76elapsed

time rshell --quiet 'exit'

0.00user 0.00system 0:00.76elapsed 0%CPU (0avgtext+0avgdata 5140maxresident)k
0inputs+0outputs (1338major+0minor)pagefaults 0swaps

With -p option: 1.77elapsed

time rshell --quiet -p COM6 'exit'

0.00user 0.00system 0:01.77elapsed 0%CPU (0avgtext+0avgdata 5128maxresident)k
0inputs+0outputs (1336major+0minor)pagefaults 0swaps
@heeplr
Copy link

heeplr commented Jan 11, 2023

can confirm this on linux:

$ time rshell --debug --port /dev/ttyACM0 cp -r ./src/* "/pyboard"
Debug = True
Port = /dev/ttyACM0
Baud = 115200
User = micro
Password = python
Wait = 0
List = 0
nocolor = 0
ascii = 0
Timing = 0
Quiet = 0
BUFFER_SIZE = 512
Cmd = [cp, -r, ./src/main.py, /pyboard]
Using buffer-size of 32
Connecting to /dev/ttyACM0 (buffer-size 32)...
Trying to connect to REPL  connected
Retrieving sysname ... ----- About to send 205 bytes of code to the pyboard -----
def sysname():
    try:
        import os
        return repr(os.uname().sysname)
    except:
        return repr('unknown')
output = sysname()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"'rp2'\r\n"
-----
rp2
Testing if ubinascii.unhexlify exists ... ----- About to send 224 bytes of code to the pyboard -----
def test_unhexlify():
    import ubinascii
    try:
        _ = ubinascii.unhexlify
        return True
    except:
        return False
output = test_unhexlify()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'True\r\n'
-----
Y
Retrieving root directories ... ----- About to send 150 bytes of code to the pyboard -----
def listdir(dirname):
    import os
    return os.listdir(dirname)
output = listdir('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"['config.json', 'main.py']\r\n"
-----
/config.json/ /main.py/
Setting time ... ----- About to send 1250 bytes of code to the pyboard -----
def set_time(rtc_time):
    rtc = None
    try:
        import pyb
        rtc = pyb.RTC()
        rtc.datetime(rtc_time)
    except:
        try:
            import pycom
            rtc_time2 = (rtc_time[0], rtc_time[1], rtc_time[2], rtc_time[4], rtc_time[5], rtc_time[6])
            import machine
            rtc = machine.RTC()
            rtc.init(rtc_time2)
        except:
            try:
                import machine
                rtc = machine.RTC()
                try:
                    rtc.datetime(rtc_time)
                except:
                    rtc.init(rtc_time)
            except:
                try:
                    import os
                    if os.uname().sysname == 'rp2':
                        setup_0 = rtc_time[0] << 12 | rtc_time[1] << 8 | rtc_time[2]
                        setup_1 = (rtc_time[3] % 7) << 24 | rtc_time[4] << 16 | rtc_time[5] << 8 | rtc_time[6]
                        machine.mem32[0x4005c004] = setup_0
                        machine.mem32[0x4005c008] = setup_1
                        machine.mem32[0x4005c00c] |= 0x10
                except:
                    pass
output = set_time((2023, 1, 11, 3, 12, 10, 9, 0))
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'None\r\n'
-----
Jan 11, 2023 12:10:09
Evaluating board_name ... ----- About to send 479 bytes of code to the pyboard -----
def board_name(default):
    try:
        import board
        try:
            name = board.name
        except AttributeError:
            name = default
    except ImportError:
        name = default
    except BaseException as err:
        print('Error encountered executing board.py')
        import sys
        sys.print_exception(err)
        name = default
    return repr(name)
output = board_name('pyboard')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"'pyboard'\r\n"
-----
pyboard
Retrieving time epoch ... ----- About to send 215 bytes of code to the pyboard -----
def get_time_epoch():
    import time
    try:
      return time.gmtime(0)
    except:
      return (2000, 1, 1, 0, 0, 0, 0, 0)
output = get_time_epoch()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'(1970, 1, 1, 0, 0, 0, 3, 1)\r\n'
-----
Jan 01, 1970
Executing "cp -r ./src/main.py /pyboard"
----- About to send 204 bytes of code to the pyboard -----
def get_mode(filename):
    import os
    try:
        return os.stat(filename)[0]
    except OSError:
        return 0
output = get_mode('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'16384\r\n'
-----
----- About to send 666 bytes of code to the pyboard -----
def is_visible(filename):
    return filename[0] != '.' and filename[-1] != '~'


def stat(filename):
    import os
    rstat = os.stat(filename)
    return rstat[:7] + tuple(tim + 0 for tim in rstat[7:])


def listdir_stat(dirname, show_hidden=True):
    import os
    try:
        files = os.listdir(dirname)
    except OSError:
        return None
    if dirname == '/':
        return list((file, stat('/' + file)) for file in files if is_visible(file) or show_hidden)
    return list((file, stat(dirname + '/' + file)) for file in files if is_visible(file) or show_hidden)
output = listdir_stat('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"[('config.json', (32768, 0, 0, 0, 0, 0, 16, 1673438561, 1673438561, 1673438561)), ('main.py', (32768, 0, 0, 0, 0, 0, 1018, 1673438986, 1673438986, 1673438986))]\r\n"
-----
Copying '/home/daniel/code/embedded/pico/bike-alarm/fw/src/main.py' to '/pyboard/main.py' ...
----- About to send 1747 bytes of code to the pyboard -----
def recv_file_from_host(src_file, dst_filename, filesize, dst_mode='wb'):
    import sys
    import ubinascii
    import os
    if False:
        try:
            import micropython
            micropython.kbd_intr(-1)
        except:
            pass
    try:
        import time
        with open(dst_filename, dst_mode) as dst_file:
            bytes_remaining = filesize
            if not False:
                bytes_remaining *= 2
            buf_size = 32
            write_buf = bytearray(buf_size)
            read_buf = bytearray(buf_size)
            while bytes_remaining > 0:
                sys.stdout.write('\x06')
                read_size = min(bytes_remaining, buf_size)
                buf_remaining = read_size
                buf_index = 0
                while buf_remaining > 0:
                    if False:
                        bytes_read = sys.stdin.buffer.readinto(read_buf, read_size)
                    else:
                        bytes_read = sys.stdin.readinto(read_buf, read_size)
                    time.sleep_ms(20)
                    if bytes_read > 0:
                        write_buf[buf_index:bytes_read] = read_buf[0:bytes_read]
                        buf_index += bytes_read
                        buf_remaining -= bytes_read
                if False:
                    dst_file.write(write_buf[0:read_size])
                else:
                    dst_file.write(ubinascii.unhexlify(write_buf[0:read_size]))
                if hasattr(os, 'sync'):
                    os.sync()
                bytes_remaining -= read_size
        return True
    except:
        return False
output = recv_file_from_host(None, '/main.py', 1018)
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'True\r\n'
-----
rshell --debug --port /dev/ttyACM0 cp -r ./src/* "/pyboard"  0,24s user 0,03s system 4% cpu 5,997 total

A long delay happens right after "Using buffer-size of 32". No delay without "--port" argument.

$ time rshell --debug cp -r ./src/* "/pyboard" 
Debug = True
Port = None
Baud = 115200
User = micro
Password = python
Wait = 0
List = 0
nocolor = 0
ascii = 0
Timing = 0
Quiet = 0
BUFFER_SIZE = 512
Cmd = [cp, -r, ./src/main.py, /pyboard]
Connecting to /dev/ttyACM0 (buffer-size 512)...
Trying to connect to REPL  connected
Retrieving sysname ... ----- About to send 205 bytes of code to the pyboard -----
def sysname():
    try:
        import os
        return repr(os.uname().sysname)
    except:
        return repr('unknown')
output = sysname()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"'rp2'\r\n"
-----
rp2
Testing if sys.stdin.buffer exists ... ----- About to send 209 bytes of code to the pyboard -----
def test_buffer():
    import sys
    try:
        _ = sys.stdin.buffer
        return True
    except:
        return False
output = test_buffer()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'True\r\n'
-----
Y
Retrieving root directories ... ----- About to send 150 bytes of code to the pyboard -----
def listdir(dirname):
    import os
    return os.listdir(dirname)
output = listdir('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"['config.json', 'main.py']\r\n"
-----
/config.json/ /main.py/
Setting time ... ----- About to send 1251 bytes of code to the pyboard -----
def set_time(rtc_time):
    rtc = None
    try:
        import pyb
        rtc = pyb.RTC()
        rtc.datetime(rtc_time)
    except:
        try:
            import pycom
            rtc_time2 = (rtc_time[0], rtc_time[1], rtc_time[2], rtc_time[4], rtc_time[5], rtc_time[6])
            import machine
            rtc = machine.RTC()
            rtc.init(rtc_time2)
        except:
            try:
                import machine
                rtc = machine.RTC()
                try:
                    rtc.datetime(rtc_time)
                except:
                    rtc.init(rtc_time)
            except:
                try:
                    import os
                    if os.uname().sysname == 'rp2':
                        setup_0 = rtc_time[0] << 12 | rtc_time[1] << 8 | rtc_time[2]
                        setup_1 = (rtc_time[3] % 7) << 24 | rtc_time[4] << 16 | rtc_time[5] << 8 | rtc_time[6]
                        machine.mem32[0x4005c004] = setup_0
                        machine.mem32[0x4005c008] = setup_1
                        machine.mem32[0x4005c00c] |= 0x10
                except:
                    pass
output = set_time((2023, 1, 11, 3, 12, 11, 34, 0))
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'None\r\n'
-----
Jan 11, 2023 12:11:34
Evaluating board_name ... ----- About to send 479 bytes of code to the pyboard -----
def board_name(default):
    try:
        import board
        try:
            name = board.name
        except AttributeError:
            name = default
    except ImportError:
        name = default
    except BaseException as err:
        print('Error encountered executing board.py')
        import sys
        sys.print_exception(err)
        name = default
    return repr(name)
output = board_name('pyboard')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"'pyboard'\r\n"
-----
pyboard
Retrieving time epoch ... ----- About to send 215 bytes of code to the pyboard -----
def get_time_epoch():
    import time
    try:
      return time.gmtime(0)
    except:
      return (2000, 1, 1, 0, 0, 0, 0, 0)
output = get_time_epoch()
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'(1970, 1, 1, 0, 0, 0, 3, 1)\r\n'
-----
Jan 01, 1970
Executing "cp -r ./src/main.py /pyboard"
----- About to send 204 bytes of code to the pyboard -----
def get_mode(filename):
    import os
    try:
        return os.stat(filename)[0]
    except OSError:
        return 0
output = get_mode('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'16384\r\n'
-----
----- About to send 666 bytes of code to the pyboard -----
def is_visible(filename):
    return filename[0] != '.' and filename[-1] != '~'


def stat(filename):
    import os
    rstat = os.stat(filename)
    return rstat[:7] + tuple(tim + 0 for tim in rstat[7:])


def listdir_stat(dirname, show_hidden=True):
    import os
    try:
        files = os.listdir(dirname)
    except OSError:
        return None
    if dirname == '/':
        return list((file, stat('/' + file)) for file in files if is_visible(file) or show_hidden)
    return list((file, stat(dirname + '/' + file)) for file in files if is_visible(file) or show_hidden)
output = listdir_stat('/')
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b"[('config.json', (32768, 0, 0, 0, 0, 0, 16, 1673438561, 1673438561, 1673438561)), ('main.py', (32768, 0, 0, 0, 0, 0, 1018, 1673439011, 1673439011, 1673439011))]\r\n"
-----
Copying '/home/daniel/code/embedded/pico/bike-alarm/fw/src/main.py' to '/pyboard/main.py' ...
----- About to send 1744 bytes of code to the pyboard -----
def recv_file_from_host(src_file, dst_filename, filesize, dst_mode='wb'):
    import sys
    import ubinascii
    import os
    if True:
        try:
            import micropython
            micropython.kbd_intr(-1)
        except:
            pass
    try:
        import time
        with open(dst_filename, dst_mode) as dst_file:
            bytes_remaining = filesize
            if not True:
                bytes_remaining *= 2
            buf_size = 512
            write_buf = bytearray(buf_size)
            read_buf = bytearray(buf_size)
            while bytes_remaining > 0:
                sys.stdout.write('\x06')
                read_size = min(bytes_remaining, buf_size)
                buf_remaining = read_size
                buf_index = 0
                while buf_remaining > 0:
                    if True:
                        bytes_read = sys.stdin.buffer.readinto(read_buf, read_size)
                    else:
                        bytes_read = sys.stdin.readinto(read_buf, read_size)
                    time.sleep_ms(20)
                    if bytes_read > 0:
                        write_buf[buf_index:bytes_read] = read_buf[0:bytes_read]
                        buf_index += bytes_read
                        buf_remaining -= bytes_read
                if True:
                    dst_file.write(write_buf[0:read_size])
                else:
                    dst_file.write(ubinascii.unhexlify(write_buf[0:read_size]))
                if hasattr(os, 'sync'):
                    os.sync()
                bytes_remaining -= read_size
        return True
    except:
        return False
output = recv_file_from_host(None, '/main.py', 1018)
if output is None:
    print("None")
else:
    print(output)

-----
-----Response-----
b'True\r\n'
-----
rshell --debug cp -r ./src/* "/pyboard"  0,21s user 0,03s system 30% cpu 0,775 total

@github0null
Copy link

github0null commented Aug 11, 2024

Hello,

I have also found this problem,

This line will not work on Windows when '-p COMx' is specified

if '/' in port:

I have post a PR to fix it.

#233

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants