Skip to content

Conversation

@dpgeorge
Copy link
Member

Summary

Convert the stm32 port from the old MICROPY_EVENT_POLL_HOOK macro to use the new mp_event_wait_xxx() functions in conjunction with MICROPY_INTERNAL_WFE.

This change should be functionally equivalent to the existing behaivour because mp_event_wait_ms() and mp_event_wait_indefinite() are equal to mp_handle_pending(true); __WFI();, which is what MICROPY_EVENT_POLL_HOOK was.

Testing

Tested on PYBD_SF6 running the test suite.

Trade-offs and Alternatives

The stm32 port doesn't have the ability to "wait for event" for an extended period of time, it only has wfi. So that's all that is used for MICROPY_INTERNAL_WFE, similar to the renesas-ra port.

The CYW43_EVENT_POLL_HOOK macro needed to be overridden, otherwise it would just call mp_event_handle_nowait() which would create power hungry busy loops.

Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge
Copy link
Member Author

@iabdalkader FYI

@github-actions
Copy link

Code size report:

Reference:  esp32/modesp32: Update available RTC pins for ESP32C6. [07540a8]
Comparison: stm32: Convert port to use new event waiting functions. [merge of 01f99a0]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:   -12 -0.003% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@iabdalkader
Copy link
Contributor

Thanks! I call MICROPY_EVENT_POLL_HOOK in a few external modules, I will make sure to switch to event_wait before the next release.
Regarding the changes, it's a bit confusing to see mp_event_wait_ms(1);, one would initially think it waits for 1ms, before realizing the timeout is ignored. Why not call mp_event_wait_indefinite isn't it the same since the timeout is ignored either way?

@dpgeorge
Copy link
Member Author

it's a bit confusing to see mp_event_wait_ms(1);, one would initially think it waits for 1ms, before realizing the timeout is ignored. Why not call mp_event_wait_indefinite isn't it the same since the timeout is ignored either way?

mp_event_wait_ms(1) does wait up to 1ms for the next systick to fire. It's equivalent (at the moment) to the previous MICROPY_EVENT_POLL_HOOK. I've used this call in places where the loop needs to check regularly for a variable to change, while still sleeping most of the time (to reduce power consumption).

I've used mp_event_wait_indefinite() in one location, in mp_hal_stdin_rx_chr(), because there it's waiting for an event (new input character), and matches how the alif and rp2 ports work (and maybe one day we can make a common mp_hal_stdin_rx_chr() function that all ports share).

@iabdalkader
Copy link
Contributor

iabdalkader commented Jan 14, 2026

mp_event_wait_ms(1) does wait up to 1ms for the next systick to fire

This depends on the tick rate. In practice, it waits for the next IRQ, whenever that occurs, since the timeout is ignored. Perhaps this is what confused me:

#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) __WFI()

Technically, all of those are indefinite waits (mp_event_wait_indefinite), it's not possible to wait for less than tick period. Perhaps this is what you meant by:

The stm32 port doesn't have the ability to "wait for event" for an extended period of time, it only has wfi

I checked Alif port, and this is how it's implemented:

#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) \
    do {                                 \
        if ((TIMEOUT_MS) < 0) { \
            __WFE(); \
        } else { \
            system_tick_wfe_with_timeout_us(TIMEOUT_MS * 1000); \
        } \
    } while (0)

You were right to push back on updating this, it is tricky.

At some point in the future, you may want to switch to a timer for stm32 port. This would also fix #17947

@dpgeorge
Copy link
Member Author

Technically, all of those are indefinite waits (mp_event_wait_indefinite), it's not possible to wait for less than tick period. Perhaps this is what you meant by:

The stm32 port doesn't have the ability to "wait for event" for an extended period of time, it only has wfi

The stm32 port is designed around the assumption that SysTick is the highest priority IRQ and runs at 1kHz. So a wfi instruction has exactly the correct semantics for mp_event_wait_ms(1). Namely, it waits up to 1ms for an event to occur (and the SysTick is an event that implements the 1ms timeout).

I checked Alif port, and this is how it's implemented:

Yes, I tried to make the alif port "better" than stm32 in this regard, by being tickless. Eventually I want to make the stm32 port tickless but it's a lot of work, as seen here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants