← index #6701PR #18119
Related · high · value 3.293
QUERY · ISSUE

RTC wakeup callback should be executed immediately rather than deferred

openby acutetechopened 2020-12-17updated 2024-09-13
port-stm32

AFAIK the callback invoked by RTC.wakeup is scheduled for later execution rather than being executed immediately, as the pin interrupts are.

See: https://github.com/micropython/micropython/blob/master/ports/stm32/extint.c#L657

IMHO this is undesirable behaviour. If the RTC is used to (a) wake the processor after machine.sleep() and (b) set a flag to be inspected by the main thread, then it has the effect that the flag may not be ready for inspection.

The code below illustrated the problem. I find that for correct operation it is necessary to add a delay after execution resumes and before inspecting variables changed by the callback. Commenting out the delay at line 17 results in undesirable behaviour.

I ran this on an OpenMV camera and the OpenMV github issue here provides more details of how I found this bug/feature, and some further analysis https://github.com/openmv/openmv/issues/1032

`
import machine, pyb, time

global triggered
triggered = False

def callback(arg):
global triggered
triggered = True

pyb.RTC().wakeup(1000, callback)

while (True):

machine.sleep()
# At this point the RTC will have woken us but the callback may not have been executed.
# This delay is essential to allow the callback to execute and update 'triggered'
time.sleep_ms(1)    # Required minimum delay is not known. Do not use sleep_us()

if (triggered):
    # Toggle green LED to indicate correct behaviour.
    # 'triggered' is seen as having changed
    pyb.LED(2).toggle()
else:
    # Toggle red LED to indicate incorrect behaviour.
    # 'triggered' is NOT seen as having changed
    pyb.LED(1).toggle()

triggered = False

`

CANDIDATE · PULL REQUEST

stm32: Fix passing invalid argument to RTC callback.

mergedby yn386opened 2025-09-22updated 2025-09-30
port-stm32

Summary

The folling code does not work with NUCLEO_F401RE.

from pyb import RTC

def cb(v):
    print(v)

rtc=RTC()
rtc.wakeup(1000, cb)

NameError exception occurred with following message.
The argument of callback should be accessed without exception.

Traceback (most recent call last):
  File "<stdin>", line 2, in cb
NameError: local variable referenced before assignment

To fix this issue, this PR passes EXTI_RTC_WAKEUP to callback argument.
This is equivalent behavior with ExtInt callback when ExtInt is mapped to RTC interrupt by passing an integer value.

Testing

Tested with NUCLEO_F401RE.
The argument of callback can be read (22 with NUCLEO_F401RE).

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied