Skip to content
Learn Netverks
-3

TransportError("could not enter raw repl") - mpremote FIX***

asked 15 hours ago by @qa-lfjimzokrxu9gpknadpq 0 rep · 46 views

esp32 micropython mpremotecommandcenter

mpremote/transport_serial.py", line 195, in enter_raw_repl
raise TransportError("could not enter raw repl")
mpremote.transport.TransportError: could not enter raw repl

in home/$USER/.local/lib/python3.13/site-packages/mpremote/transport_serial.py change these functions to this.

I removed the soft reset parameter and ammended the endswith() to check if it contains instead in case of extra serial noise.

Ive added self.serial.flush() after each self.serial.write() Ive also added a time.sleep(0.4) and time.sleep(0.01) to wait for the serial to flush the data. This seems to have fixed it for me.

I can enter raw repl as a user via mpremote connect /dev/ttyUSB0 repl ctrl^C ctrl^C ctrl^A If you can do the same you likely have the same issue.

If it still doesnt work try adding more time.sleep() between flushes.

def read_until(
        self, min_num_bytes, ending, timeout=10, data_consumer=None, timeout_overall=None
    ):
        """
        min_num_bytes: Obsolete.
        ending: Return if 'ending' matches.
        timeout [s]: Return if timeout between characters. None: Infinite timeout.
        timeout_overall [s]: Return not later than timeout_overall. None: Infinite timeout.
        data_consumer: Use callback for incoming characters.
            If data_consumer is used then data is not accumulated and the ending must be 1 byte long

        It is not visible to the caller why the function returned. It could be ending or timeout.
        """
        assert data_consumer is None or len(ending) == 1
        assert isinstance(timeout, (type(None), int, float))
        assert isinstance(timeout_overall, (type(None), int, float))

        data = b""
        begin_overall_s = begin_char_s = time.monotonic()
        while True:
            if data.endswith(ending):
                break
            elif self.serial.inWaiting() > 0:
                new_data = self.serial.read(1)
                if data_consumer:
                    data_consumer(new_data)
                    data = new_data
                else:
                    data = data + new_data
                begin_char_s = time.monotonic()
            else:
                if timeout is not None and time.monotonic() >= begin_char_s + timeout:
                    break
                if (
                    timeout_overall is not None
                    and time.monotonic() >= begin_overall_s + timeout_overall
                ):
                    break
            
            time.sleep(0.001)  # Avoid busy wait

        return data

    def enter_raw_repl(self, soft_reset=None, timeout_overall=30):
        self.serial.write(b"\r\x03")  # ctrl-C: interrupt any running program
        self.serial.flush()

        # flush input (without relying on serial.flushInput())
        n = self.serial.inWaiting()
        while n > 0:
            self.serial.read(n)
            n = self.serial.inWaiting()
        time.sleep(0.4)  # let any pending output flush
        self.serial.write(b"\r\x01")  # ctrl-A: enter raw REPL
        self.serial.flush()

        time.sleep(2)

        data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n", timeout_overall=timeout_overall)
        if b"raw REPL; CTRL-B to exit" not in data:
            print(data)
            raise TransportError("could not enter raw repl")

        self.in_raw_repl = True

    def exit_raw_repl(self):
        self.serial.write(b"\r\x02")  # ctrl-B: enter friendly REPL
        self.in_raw_repl = False

    def follow(self, timeout, data_consumer=None):
        # wait for normal output
        data = self.read_until(1, b"\x04", timeout=timeout, data_consumer=data_consumer)
        if not data.endswith(b"\x04"):
            raise TransportError("timeout waiting for first EOF reception")
        data = data[:-1]

        # wait for error output
        data_err = self.read_until(1, b"\x04", timeout=timeout)
        if not data_err.endswith(b"\x04"):
            raise TransportError("timeout waiting for second EOF reception")
        data_err = data_err[:-1]

        # return normal and error output
        return data, data_err

    def raw_paste_write(self, command_bytes):
        # Read initial header, with window size.
        data = self.serial.read(2)
        window_size = struct.unpack("<H", data)[0]
        window_remain = window_size

        # Write out the command_bytes data.
        i = 0
        while i < len(command_bytes):
            while window_remain == 0 or self.serial.inWaiting():
                data = self.serial.read(1)
                if data == b"\x01":
                    # Device indicated that a new window of data can be sent.
                    window_remain += window_size
                elif data == b"\x04":
                    # Device indicated abrupt end.  Acknowledge it and finish.
                    self.serial.write(b"\x04")
                    self.serial.flush()
                    return
                else:
                    # Unexpected data from device.
                    raise TransportError("unexpected read during raw paste: {}".format(data))
            # Send out as much data as possible that fits within the allowed window.
            b = command_bytes[i : min(i + window_remain, len(command_bytes))]
            self.serial.write(b)
            self.serial.flush()
            window_remain -= len(b)
            i += len(b)

        # Indicate end of data.
        self.serial.write(b"\x04")
        self.serial.flush()

        # Wait for device to acknowledge end of data.
        data = self.read_until(1, b"\x04")
        if not data.endswith(b"\x04"):
            raise TransportError("could not complete raw paste: {}".format(data))

Comments on this question (0)

Use comments to ask for clarification — answers go in the answer box below.

Log in to comment on this question.

0 answers

Your answer