8000 rp2: Disable the LWIP tick timer when not needed. by projectgus · Pull Request #17272 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

rp2: Disable the LWIP tick timer when not needed. #17272

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

Merged
merged 1 commit into from
May 21, 2025

Conversation

projectgus
Copy link
Contributor
@projectgus projectgus commented May 9, 2025

Summary

Closes #16181. Prevents lightsleep being woken up every 64ms to service LWIP timers, when:

  1. No netif is up, and
  2. No TCP sockets are active

The TCP socket check may not be strictly necessary, but without ticking the tcp timer they won't ever time out by themselves.

It means that it's possible to do:

wlan.disconnect()
machine.lightsleep(5000)
wlan.connect(...)

... and get the full sleep time, but also possible to do

while some_condition():
    machine.lightsleep(5000)

... and Python will wake up every 64ms if Wi-Fi is active, but power consumption is still lower than it would be otherwise.

(Not massively lower, on RPI_PICO_W I measure 53mA idle at REPL with Wi-Fi associated, and 40mA in a while True: machine.lightsleep(1000) loop. There is probably potential to make this better by having lightsleep put the CYW43 driver into a lower power mode.)

This work was funded through GitHub Sponsors.

Testing

Important: This PR has only been tested cherry-picked onto the branch for #16454. It is marked as a draft until that PR is merged and it can be rebased.

  • Ran multi_net and multi_wlan tests on RPI_PICO_W and RPI_PICO2_W. Same failures as reported against master.

Trade-offs and Alternatives

  • There is some risk that some part of LWIP doesn't like being starved of timeouts for a long period after a network interface goes down. However, it looks like it will be OK - the main thing is TCP/IP socket timeouts and LWIP will keep ticking until these time out.
  • Could make LWIP timer not a wake-up source, but this is quite difficult and does prevent using light sleep effectively with Wi-Fi.
  • Could make LWIP timer wake-ups not return from lightsleep (i.e. the hardware wakes up, services LWIP, then goes back to sleep), but this is also quite fiddly to do (need to check the wake source each time).
  • Semi-related: there is also a LWIP function sys_timeouts_sleeptime() which could be used to have the LWIP timer run at an exact time instead of at a constant tick rate. However, a number of LWIP "cyclic" timers run every 100ms right now so this change seems like it would be of limited benefit, it would add some code size, and the lwip tick callback is also used to poll the wiznet5k driver.

Copy link
github-actions bot commented May 9, 2025

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:  +112 +0.012% RPI_PICO_W[incl +8(bss)]
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@madozu
Copy link
madozu commented May 9, 2025

I did a lot of testing with the current master branch and pull requests #16454 and #17272 applied.

All the "early wakeup" scenarios I was experiencing when using machine.lightsleep() are solved --> Great news, many thanks to @projectgus for providing a good solution 😄

So far, I did not encounter any negative side effects.

@dpgeorge
Copy link
Member

I haven't tested this yet (will do once it's rebased now that #16454 is merged) but the logic looks good!

@dpgeorge dpgeorge added this to the release-1.26.0 milestone May 13, 2025
@projectgus projectgus force-pushed the bugfix/rp2_lwip_ticks branch from f02fa2e to 3b17999 Compare May 15, 2025 00:55
@projectgus projectgus marked this pull request as ready for review May 15, 2025 00:55
@projectgus
Copy link
Contributor Author

Rebased, addressed review comments, re-ran multi_net and multi_wifi tests on RPI_PICO_W & RPI_PICO2_W with same results.

  • On my local setup multi_net/udp_data.py fails intermittently to packet loss - but I have a mediocre wifi signal here.
  • multi_net/tls_dtls_server_client.py fails when the rp2 is instance 1.
  • multi_wlan I realised has a bug when STA is rp2 and a wifi connection is already active. Will submit separate PR to fix.

Prevents lightsleep being woken up every 64ms to service LWIP timers, when:

1. No netif is up, and
2. No TCP sockets are active

The TCP socket check may not be strictly necessary, but without ticking the
tcp timer they won't ever time out by themselves.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
Copy link
Member
@dpgeorge dpgeorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on RPI_PICO_W and RPI_PICO2_W, running all possible tests:

  • tests/ports/rp2/rp2_lightsleep_thread.py fails on both of them, but that's expected (and fails also on master)
  • tests/multi_net/udp_data_multi.py fails when one of the boards is instance 0, and also fails on master. I was sure this was working when I wrote the test so maybe it's down to local WLAN variability.

All other tests pass for me.

@dpgeorge dpgeorge force-pushed the bugfix/rp2_lwip_ticks branch from 3b17999 to 4545eb8 Compare May 21, 2025 13:51
@dpgeorge dpgeorge merged commit 4545eb8 into micropython:master May 21, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

lightsleep(n) returns immediately on pico-w or pico with network imported lightsleep on Pico W regression for 1.24.0
3 participants
0