Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.2k
rp2: Fix power consumption when sleeping with a timeout.#15398
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
github-actionsbot commentedJul 3, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Code size report:
|
This comment was marked as outdated.
This comment was marked as outdated.
9abc812
toe1fedbd
Compare
Not sure why this is, I assume some lucky linker combo? There is definitely new code being added in this PR. |
I've tested this PR on a Pico and Pico W and the power consumption looks good for |
Fixes a regression introduced in3af006ewhere WFE never blocked in `mp_wfe_or_timeout()` function and wouldbusy-wait instead. This increases power consumption measurably.Root cause is that `mp_wfe_or_timeout()` calls soft timer functions that(after the regression) call `recursive_mutex_enter()` and`recursive_mutex_exit()`. The exit calls`lock_internal_spin_unlock_with_notify()` and the default pico-sdkimplementation of this macro issues a SEV which negates the WFE thatfollows it, meaning the CPU never suspends.Seehttps://forums.raspberrypi.com/viewtopic.php?p=2233908 for moredetails.The fix in this comment adds a custom "nowait" variant mutex that doesn'tdo WFE/SEV, and uses this one for PendSV. This will use more power whenthere's contention for the PendSV mutex as the other core will spin, butthis shouldn't happen very often.This work was funded through GitHub Sponsors.Signed-off-by: Angus Gratton <angus@redyak.com.au>
If core1 executes `mp_wfe_or_timeout()` then it needs to receive aninterrupt or a SEV to resume execution, but the soft timer interrupt onlyfires on core 0. This fix adds a SEV to the soft timer interrupt handler.This issue was masked by the issue fixed in the previous commit, as WFEpreviously wasn't suspending properly.Verified via the existing thread_sleep2 test.This work was funded through GitHub Sponsors.Signed-off-by: Angus Gratton <angus@redyak.com.au>
e1fedbd
to9db16cf
Compare9db16cf
intomicropython:masterUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Summary
Fixes a regression introduced in3af006e (part of#13329), where WFE never blocked in
mp_wfe_or_timeout()
function and would busy-wait instead. This increases power consumption measurably. Originally found when testing#15345Root cause is that
mp_wfe_or_timeout()
calls soft timer functions that (after the regression) callrecursive_mutex_enter()
andrecursive_mutex_exit()
. Mutex exit callslock_internal_spin_unlock_with_notify()
and the default pico-sdk implementation of this macro issues a SEV which negates the WFE that follows it, meaning the CPU never suspends.Seehttps://forums.raspberrypi.com/viewtopic.php?p=2233908 for more details.
The fix in this comment adds a custom "nowait" variant mutex that doesn't do WFE/SEV, and uses this one for PendSV. This will use more power when there's contention for the PendSV mutex as the other core will spin, but this shouldn't happen very often.
Additional commit fixes a bug that was masked by this bug, specifically that core1 didn't have any way to resume from WFE (because the soft timer interrupt only triggers on core0).
Testing
Tested on PICO board while measuring USB power consumption. Prior to this fix,
time.sleep(1)
uses 3-4mA more power than sitting at an idle REPL. After this fix, the power consumption is approximately the same (actually approx 0.3mA higher while sleeping, I assume due to the extra clock or maybe because of USB traffic).Also ran the full rp2 test suite multiple times. The thread_sleep2 test successfully found the core1 bug mentioned above.
Also connected a PICO-W to a Wi-Fi network.
Trade-offs and Alternatives
This is the third fix I wrote for this issue(!)
mp_wfe_or_timeout()
with a dedicated hardware timer alarm. This works fine for single core, but in dual core there's potential for both cores to enter this function at the same time meaning this approach is no longer simple.This approach adds a bit more code size, but it means the low power mutex variant is still used everywhere except for PendSV - and there shouldn't be a lot of lock contention over PendSV.