Skip to content

Pico W: sleep_us causes execution to hang #12873

Closed

Description

@danielteel

Firmware version: MicroPython v1.21.0 on 2023-10-06; Raspberry Pi Pico W with RP2040

On both of my Pico W devices, if I execute the below code on a freshly booted device, it causes execution to hang.

import time

time.sleep_us(5)
time.sleep_us(10)
time.sleep_us(5)
time.sleep_us(10)

time.sleep_ms(1000)
print('its been a second')#doesnt print

The expected output is

its been a second

But the output is

To reproduce this:

  1. create a file called bug.py, insert the above code into it
  2. upload the file to the pico w
  3. do a hard reset
  4. in the REPL terminal execute import bug
  5. execution will hang and will not print the text

Activity

  1. scruss commented on Nov 3, 2023

    @scruss
    SponsorContributor

    see also related issue [Resolved - MicroPython is broken] Timers plus sleep_ms and sleep_us oddness - Raspberry Pi Forums, where poster's code with sleep_ms() works but when replaced with sleep_us() fails.

    (OP on Raspberry Pi forum is unable to use github, for some reason.)

  2. dpgeorge commented on Nov 14, 2023

    @dpgeorge
    Member

    I can reproduce the issue. It's apparent only with Pico W firmware and seems to be related to having the lwIP 64ms alarm running.

  3. scruss commented on Nov 14, 2023

    @scruss
    SponsorContributor

    This code hangs on both Pico W and Pico (both v1.21.0):

    # test_us - from https://forums.raspberrypi.com/viewtopic.php?t=312874
    from machine import Timer
    import time
    
    count = 0
    
    
    def tick(timer):
        global count
        count += 1
    
    
    Timer().init(freq=1_000, mode=Timer.PERIODIC, callback=tick)
    
    while True:
        count = 0
        # time.sleep_ms(1_000)
        time.sleep_us(1_000_000)
        n = count
        print("{} ticks per second".format(n))

    Substituting the commented-out time.sleep_ms(1_000) runs as expected.

  4. dpgeorge commented on Nov 14, 2023

    @dpgeorge
    Member

    Thanks @scruss for that additional test. I can confirm that it displays similar symptoms to the original issue: it seems to hang (no output is printed), but if you press a key at the REPL it does start printing. That's consistent with the RP2040 being blocked in a WFE with no interrupt to wake it, and pressing a key sends a USB packet and wakes it up.

    Initial investigation by @projectgus and myself have us suspecting a bug in pico-sdk's alarm pool / pairing heap, when there are multiple timers some of them get dropped. (Note that each machine.Timer allocates a new alarm pool timer, each call to sleep_us and sleep_ms use the alarm pool, and also sitting idle at the REPL uses the alarm pool to wait efficiently.)

  5. dpgeorge commented on Nov 20, 2023

    @dpgeorge
    Member

    I reported this issue to pico-sdk: raspberrypi/pico-sdk#1552

  6. projectgus commented on Jun 4, 2024

    @projectgus
    Contributor

    This should now be fixed in MicroPython as #13329 was cherry-picked in 74fb42a.

    (The root cause in the alarm pool of pico-sdk probably still exists, and MicroPython still uses the alarm pool however now it is only used for longer timeouts that don't seem to trigger this bug. See the linked commit for more details about removing alarm pool from MP entirely.)

  7. added this to the release-1.24.0 milestone on Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions