Skip to content

tud_task() inhibits wfe on rp2350, turns low power loops into busy loops #2495

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

Open
rlcamp opened this issue Jun 1, 2025 · 1 comment
Open

Comments

@rlcamp
Copy link

rlcamp commented Jun 1, 2025

The common pattern of

while (!condition) {
    tud_task();
    __wfe();
}

which should put the processor to sleep between interrupts, becomes a busy loop by default on RP2350 due to the use of pico-sdk spinlocks within tud_task(), which behave like sev() due to reasons discussed in #1812. Mitigations include disabling EXTEXCALL (which modifies the behaviour of ALL atomics and other exclusive load/stores between cores), or putting

#undef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_NONE

in tusb_config.h, disabling the pico-specific code paths in the TinyUSB OS abstraction layer. The latter is less of a big hammer but still has consequences wr interacting with TinyUSB from both cores.

@peterharperuk
Copy link
Contributor

Maybe you should do something like this instead?

    absolute_time_t timeout_time = make_timeout_time_ms(10);
    do {
      if (tud_task_event_ready()) break;
    } while (!best_effort_wfe_or_timeout(timeout_time));
    tud_task(); // tinyusb device task

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants