8000 rp2,docs: Stop machine.idle() blocking indefinitely, update docs. by projectgus · Pull Request #15345 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

rp2,docs: Stop machine.idle() blocking indefinitely, update docs. #15345

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 2 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions docs/library/machine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,20 @@ Power related functions

.. function:: idle()

Gates the clock to the CPU, useful to reduce power consumption at any time during
short or long periods. Peripherals continue working and execution resumes as soon
as any interrupt is triggered (on many ports this includes system timer
interrupt occurring at regular intervals on the order of millisecond).
Gates the clock to the CPU, useful to reduce power consumption at any time
during short or long periods. Peripherals continue working and execution
resumes as soon as any interrupt is triggered, or at most one millisecond
after the CPU was paused.

It is recommended to call this function inside any tight loop that is
continuously checking for an external change (i.e. polling). This will reduce
power consumption without significantly impacting performance. To reduce
power consumption further then see the :func:`lightsleep`,
:func:`time.sleep()` and :func:`time.sleep_ms()` functions.

.. function:: sleep()

.. note:: This function is deprecated, use `lightsleep()` instead with no arguments.
.. note:: This function is deprecated, use :func:`lightsleep()` instead with no arguments.

.. function:: lightsleep([time_ms])
deepsleep([time_ms])
Expand Down
2 changes: 1 addition & 1 deletion ports/rp2/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) {
}

static void mp_machine_idle(void) {
__wfe();
MICROPY_INTERNAL_WFE(1);
}

static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
Expand Down
36 changes: 36 additions & 0 deletions tests/ports/rp2/rp2_machine_idle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import machine
import time

# Verify that machine.idle() resumes execution within 0.1 and 1.1ms (should be
# 1ms max but allowing for some overhead).
#
# (A minimum sleep time for machine.idle() isn't specified but in a system like
# this with no active interrupts then we should expect some idle time before
# resuming. If it's consistently resuming immediately then that indicates a bug
# is preventing proper idle.)
#
# This test doesn't contain any rp2-specific code, but rp2 is currently the only
# tickless port - which is what led to the bug this is a regression test for.
# Some other ports (unix, esp32) have idle behaviour that resumes immediately on
# a quiet system, so this test is also less useful for those.
#
# Verification uses the average idle time, as individual iterations will always
# have outliers due to interrupts, scheduler, etc.

ITERATIONS = 500
total = 0

for _ in range(ITERATIONS):
before = time.ticks_us()
machine.idle()
total += time.ticks_diff(time.ticks_us(), before)

total /= 1000 # us to ms
average = total / ITERATIONS

# print(f"Total {total}ms average {average}ms") # uncomment for debug

if 0.1 < average < 1.1:
print("PASS")
else:
print(f"Total {total}ms average {average}ms, out of spec")
1 change: 1 addition & 0 deletions tests/ports/rp2/rp2_machine_idle.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PASS
Loading
0