8000 RP2040 will lockup if a watchdog timeout occurs while lightsleep() is running · Issue #17228 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content
RP2040 will lockup if a watchdog timeout occurs while lightsleep() is running #17228
Open
@cpottle9

Description

@cpottle9

Port, board and/or hardware

Raspberry PI Pico

MicroPython version

MicroPython v1.25.0 on 2025-04-15; Raspberry Pi Pico with RP2040

Reproduction

Test file named wdt_lightsleep.py.

from machine import lightsleep, WDT

wdt = WDT(timeout=3000)
lightsleep(5000)

Do 'mpremote run wdt_lightsleep.py'.

>> mpremote run wdt_lightsleep.py 
Traceback (most recent call last):
  File "/home/picompute/.local/bin/mpremote", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/mpremote/main.py", line 569, in main
    handler_func(state, args)
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/mpremote/commands.py", line 463, in do_run
    _do_execbuffer(state, buf, args.follow)
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/mpremote/commands.py", line 437, in _do_execbuffer
    ret, ret_err = state.transport.follow(timeout=None, data_consumer=stdout_write_bytes)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/mpremote/transport_serial.py", line 184, in follow
    data = self.read_until(1, b"\x04", timeout=timeout, data_consumer=data_consumer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/mpremote/transport_serial.py", line 123, in read_until
    elif self.serial.inWaiting() > 0:
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/serial/serialutil.py", line 594, in inWaiting
    return self.in_waiting
           ^^^^^^^^^^^^^^^
  File "/home/picompute/.local/pipx/venvs/mpremote/lib/python3.11/site-packages/serial/serialposix.py", line 549, in in_waiting
    s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 5] Input/output error
>> mpremote
mpremote: no device found

Expected behaviour

Expect it to behave the same as if lightsleep were replaced with time.sleep_ms.
Call this test file wdt_sleep_ms.py

from machine import WDT
from time import sleep_ms

wdt = WDT(timeout=3000)
sleep_ms(5000)

In this case, after do 'mpremote run wdt_sleep_ms.py'.
After 3 seconds mpremote will report an OSError because the RP2040 does a soft reset.
Run mpremote again and it will connect successfully.

Observed behaviour

The RP2040 seems to get stuck. After running 'mpremote run wdt_lightsleep.py' attempts to connect running mpremote fail.
On my Raspberry Pi 4 I see an error message of 'mpremote: no device found'.

A power cycle is required to recover.

One more observation, I have a USB power meter connected between the PI 4 and RPI Pico.
Normally it reports about 19 milli-amps consumed, about 5 milli-amps while the lightsleep is running.
After the test completes it reports about 1.00 milli-amps.

Additional Information

I have changes to lightsleep in modmachine.c which fix this problem.
I will prepare a pull request with this fix.

The root cause is lightsleep turns off the ROSC.
When the watchdog timeout occurs the Power-On State Machine does not re-initialize it.
This occurs because the PICO-SDK function _watchdog_enable() zero's sm_hw->wdsel bits for the ROSC and XOSC.

The behavior reported here is seen on RP2040 only.

Code of Conduct

Yes, I agree

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0