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

fix: non-standard default baud rate (RDT-764) #274

Merged
merged 1 commit into from
Apr 23, 2024

Conversation

ronmov
Copy link
Contributor

@ronmov ronmov commented Apr 22, 2024

Caused errors while not explicitly providing the ESPBAUD environment variable due to non-standard default baud rate.

Click here to expand the traceback (not for the faint of heart)
Detecting the Python interpreter
Checking "python3" ...
Python 3.8.10
"python3" has been detected
Checking Python compatibility
Checking other ESP-IDF version.
Adding ESP-IDF tools to PATH...
Checking if Python packages are up to date...
The following Python requirements are not satisfied:
Requirement 'pytest-embedded-idf~=0.8' was not met. Installed version: 1.8.3
Requirement 'protobuf<=3.20.1' was not met. Installed version: 5.26.1
Requirement 'pytest-embedded-qemu~=0.8' was not met. Installed version: 1.8.3
Requirement 'idf-build-apps~=1.0' was not met. Installed version: 2.3.1
Requirement 'pytest-embedded-serial-esp~=0.8' was not met. Installed version: 1.8.3
To install the missing packages, please run "install.sh"
Diagnostic information:
    IDF_PYTHON_ENV_PATH: /opt/esp/python_env/idf5.0_py3.8_env
    Python interpreter used: /opt/esp/python_env/idf5.0_py3.8_env/bin/python
Constraint file: /opt/esp/espidf.constraints.v5.0.txt
Requirement files:
 - /opt/esp/idf/tools/requirements/requirements.core.txt
 - /opt/esp/idf/tools/requirements/requirements.pytest.txt
Python being checked: /opt/esp/python_env/idf5.0_py3.8_env/bin/python
============================= test session starts ==============================
platform linux -- Python 3.8.10, pytest-8.1.1, pluggy-1.5.0
rootdir: /tmp/KvsTwOjmVy
plugins: sigrok-cli-pytest-plugin-0.3.1, anyio-4.3.0, mock-3.14.0, embedded-1.8.3, rerunfailures-14.0
collected 1 item

main/test_sanity.py 2024-04-22 14:55:36 Serial port /dev/ttyUSB0
2024-04-22 14:55:36 Connecting....
2024-04-22 14:55:36 Connecting....
2024-04-22 14:55:37 esptool.py v4.7.0
2024-04-22 14:55:37 Found 1 serial ports
2024-04-22 14:55:37 Chip is ESP32-D0WDQ6 (revision v1.0)
2024-04-22 14:55:37 Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
2024-04-22 14:55:37 Crystal is 40MHz
2024-04-22 14:55:37 MAC: **:**:**:**:**:**
2024-04-22 14:55:37 Uploading stub...
2024-04-22 14:55:37 Running stub...
2024-04-22 14:55:37 Stub running...
2024-04-22 14:55:37 Changing baud rate to 1000000
2024-04-22 14:55:37 Changed.
E

==================================== ERRORS ====================================
________________________ ERROR at setup of test_sanity _________________________

argv = ['--after', 'hard_reset', '--before', 'default_reset', '--chip', 'esp32', ...]
esp = <esptool.targets.esp32.ESP32StubLoader object at 0x7f661574b970>

    def main(argv=None, esp=None):
        """
        Main function for esptool
    
        argv - Optional override for default arguments parsing (that uses sys.argv),
        can be a list of custom arguments as strings. Arguments and their values
        need to be added as individual items to the list
        e.g. "-b 115200" thus becomes ['-b', '115200'].
    
        esp - Optional override of the connected device previously
        returned by get_default_connected_device()
        """
    
        # Intentianally deleted implementation of this function because GitHub has a character limit in the PR description
    
            # Check flash chip connection
            if not esp.secure_download_mode:
                try:
>                   flash_id = esp.flash_id()

/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/__init__.py:849: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:931: in flash_id
    self.cache["flash_id"] = self.run_spiflash_command(SPIFLASH_RDID, b"", 24)
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:1336: in run_spiflash_command
    old_spi_usr = self.read_reg(SPI_USR_REG)
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:752: in read_reg
    val, data = self.command(
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:436: in command
    p = self.read()
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:369: in read
    return next(self._slip_reader)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

port = Serial<id=0x7f66157a4130, open=True>(port='/dev/ttyUSB0', baudrate=1000000, bytesize=8, parity='N', stopbits=1, timeout=0.05, xonxoff=False, rtscts=False, dsrdtr=False)
trace_function = <bound method ESPLoader.trace of <esptool.targets.esp32.ESP32StubLoader object at 0x7f661574b970>>

    def slip_reader(port, trace_function):
        """Generator to read SLIP packets from a serial port.
        Yields one full SLIP packet at a time, raises exception on timeout or invalid data.
    
        Designed to avoid too many calls to serial.read(1), which can bog
        down on slow systems.
        """
    
        def detect_panic_handler(input):
            """
            Checks the input bytes for panic handler messages.
            Raises a FatalError if Guru Meditation or Fatal Exception is found, as both
            of these are used between different ROM versions.
            Tries to also parse the error cause (e.g. IllegalInstruction).
            """
    
            guru_meditation = (
                rb"G?uru Meditation Error: (?:Core \d panic'ed \(([a-zA-Z ]*)\))?"
            )
            fatal_exception = rb"F?atal exception \(\d+\): (?:([a-zA-Z ]*)?.*epc)?"
    
            # Search either for Guru Meditation or Fatal Exception
            data = re.search(
                rb"".join([rb"(?:", guru_meditation, rb"|", fatal_exception, rb")"]),
                input,
                re.DOTALL,
            )
            if data is not None:
                cause = [
                    "({})".format(i.decode("utf-8"))
                    for i in [data.group(1), data.group(2)]
                    if i is not None
                ]
                cause = f" {cause[0]}" if len(cause) else ""
                msg = f"Guru Meditation Error detected{cause}"
                raise FatalError(msg)
    
        partial_packet = None
        in_escape = False
        successful_slip = False
        while True:
            waiting = port.inWaiting()
            read_bytes = port.read(1 if waiting == 0 else waiting)
            if read_bytes == b"":
                if partial_packet is None:  # fail due to no data
                    msg = (
                        "Serial data stream stopped: Possible serial noise or corruption."
                        if successful_slip
                        else "No serial data received."
                    )
                else:  # fail during packet transfer
                    msg = "Packet content transfer stopped (received {} bytes)".format(
                        len(partial_packet)
                    )
                trace_function(msg)
>               raise FatalError(msg)
E               esptool.util.FatalError: Packet content transfer stopped (received 6 bytes)

/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/loader.py:1566: FatalError

During handling of the above exception, another exception occurred:

args = ()
kwargs = {'_fixture_classes_and_options': ClassCliOptions(classes={'app': <class 'pytest_embedded_idf.app.IdfApp'>, 'serial': <...ded_idf.app.IdfApp object at 0x7f66157859d0>, 'msg_queue': <pytest_embedded.log.MessageQueue object at 0x7f66164dad00>}
_close_or_terminate = <function multi_dut_generator_fixture.<locals>.wrapper.<locals>._close_or_terminate at 0x7f6615796160>
res = None

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        def _close_or_terminate(obj):
            if obj is None:
                del obj
                return
    
            try:
                if isinstance(obj, (subprocess.Popen, multiprocessing.process.BaseProcess)):
                    obj.terminate()
                    obj.kill()
                elif isinstance(obj, io.IOBase):
                    try:
                        obj.close()
                    except Exception as e:
                        logging.debug('file %s closed failed with error: %s', obj, str(e))
                else:
                    try:
                        obj.close()
                    except AttributeError:
                        try:
                            obj.terminate()
                        except AttributeError:
                            pass
                    except Exception as e:
                        logging.debug('Not properly caught object %s: %s', obj, str(e))
            except Exception as e:
                logging.debug('%s: %s', obj, str(e))
                return  # swallow up all error
            finally:
                referrers = gc.get_referrers(obj)
                for _referrer in referrers:
                    if isinstance(_referrer, list):
                        for _i, val in enumerate(_referrer):
                            if val is obj:
                                _referrer[_i] = None
                    elif isinstance(_referrer, dict):
                        for key, value in _referrer.items():
                            if value is obj:
                                _referrer[key] = None
                del obj
    
        if _COUNT == 1:
            res = None
            try:
>               res = func(*args, **kwargs)

/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded/plugin.py:468: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded/plugin.py:1347: in serial
    return cls(**_drop_none_kwargs(kwargs))
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_idf/serial.py:42: in __init__
    super().__init__(
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_serial_esp/serial.py:128: in __init__
    super().__init__(msg_queue=msg_queue, port=self.esp._port, baud=baud, meta=meta, **kwargs)
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_serial/serial.py:90: in __init__
    self._start()
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_idf/serial.py:76: in _start
    self.flash()
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_serial_esp/serial.py:170: in wrapper
    ret = func(self, *args, **kwargs)
/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/pytest_embedded_idf/serial.py:198: in flash
    esptool.main(_args, esp=self.esp)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

argv = ['--after', 'hard_reset', '--before', 'default_reset', '--chip', 'esp32', ...]
esp = <esptool.targets.esp32.ESP32StubLoader object at 0x7f661574b970>

    def main(argv=None, esp=None):
        """
        Main function for esptool
    
        argv - Optional override for default arguments parsing (that uses sys.argv),
        can be a list of custom arguments as strings. Arguments and their values
        need to be added as individual items to the list
        e.g. "-b 115200" thus becomes ['-b', '115200'].
    
        esp - Optional override of the connected device previously
        returned by get_default_connected_device()
        """
    
        # Intentianally deleted implementation of this function because GitHub has a character limit in the PR description
    
                except FatalError as e:
>                   raise FatalError(f"Unable to verify flash chip connection ({e}).")
E                   esptool.util.FatalError: Unable to verify flash chip connection (Packet content transfer stopped (received 6 bytes)).

/opt/esp/python_env/idf5.0_py3.8_env/lib/python3.8/site-packages/esptool/__init__.py:867: FatalError
------------------------------ Captured log setup ------------------------------
WARNING  root:app.py:100 /tmp/KvsTwOjmVy/build/config/sdkconfig.json doesn't exist. Skipping...
--------------- generated xml file: /tmp/KvsTwOjmVy/results.xml ----------------
=========================== short test summary info ============================
ERROR main/test_sanity.py::test_sanity - esptool.util.FatalError: Unable to v...
=============================== 1 error in 4.42s ===============================

When manually specifing the baud rate using the ESPBAUD environment variable to 921600 the test runs successfully using pytest

Caused errors while not explicitly providing the ESPBAUD environment variable due to non-standard default baud rate.
@hfudev hfudev requested review from horw and hfudev April 22, 2024 21:27
@radimkarnis
Copy link

Hello @ronmov,
I agree that 921600 is a more common baud rate. This LGTM! Thank you.

@hfudev hfudev merged commit 973a192 into espressif:main Apr 23, 2024
4 of 5 checks passed
@github-actions github-actions bot changed the title fix: non-standard default baud rate fix: non-standard default baud rate (RDT-764) Apr 23, 2024
@hfudev
Copy link
Member

hfudev commented Apr 23, 2024

Thanks for your PR! Released with v1.8.4.

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

Successfully merging this pull request may close these issues.

3 participants