-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Raspberry Pi Pico _thread OSError: TinyUSB callback can't recurse #15390
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
Comments
Thanks @IDreamed for the clear report. I ran into this same thing earlier today while testing something else, hadn't been back to check more closely. |
@projectgus My pleasure. |
I'm receiving the same running the micropython RP2 multicore example. Every version since v1.22 results in some or other freeze or crash when creating a thread. I've pulled and built the master branch today and received the same error as you with the example:
Any advice would be appreciated since my application needs multicore and the USBDevice class added in v1.23 |
Sorry I can't help, I don’t know much about embedded development, I suspect these issues are because the RP2’s multithread runs on real cores, which leads to resource contention since there can only be one core. I have encountered other issues related to _thread and USB. |
I got the same error text but with a different hex value only after flashing the firmware on my raspberry pico (on pico w this is even worse and the device is not recognized anymore): |
Looks like there was a long standing underlying bug here when using rp2 threads, where either CPU may poll CDC input and trigger the TinyUSB task. TinyUSB could run on both CPUs concurrently, which may have lead to some incorrect behaviour. The race started triggering an exception when runtime USB support was added, and a check was added for the USB task recursing on itself from a Python handler function. The race is most commonly triggered when working from the interactive REPL, even a minimal running thread can trigger it. This commit adds a test case that triggers it in a different way (polling stdin from a thread). Fix is to add a port-level macro that indicates whether the TinyUSB task can run. Closes micropython#15390. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Looks like there was a long standing underlying bug here when using rp2 threads, where either CPU may poll CDC input and trigger the TinyUSB task. TinyUSB could run on both CPUs concurrently, which may have lead to some incorrect behaviour. The race started triggering an exception when runtime USB support was added, and a check was added for the USB task recursing on itself from a Python handler function. The race is most commonly triggered when working from the interactive REPL, even a minimal running thread can trigger it. This commit adds a test case that triggers it in a different way (polling stdin from a thread). Fix is to add a port-level macro that indicates whether the TinyUSB task can run. Closes micropython#15390. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Looks like there was a long standing underlying bug here when using rp2 threads, where either CPU may poll CDC input and trigger the TinyUSB task. TinyUSB could run on both CPUs concurrently, which may have lead to some incorrect behaviour. The race started triggering an exception when runtime USB support was added, and a check was added for the USB task recursing on itself from a Python handler function. The race is most commonly triggered when working from the interactive REPL, even a minimal running thread can trigger it. This commit adds a test case that triggers it in a different way (polling stdin from a thread). Fix is to add a port-level macro that indicates whether the TinyUSB task can run. Closes micropython#15390. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Looks like there was a long standing underlying bug here when using rp2 threads, where either CPU may poll CDC input and trigger the TinyUSB task. TinyUSB could run on both CPUs concurrently, which may have lead to some incorrect behaviour. The race started triggering an exception when runtime USB support was added, and a check was added for the USB task recursing on itself from a Python handler function. The race is most commonly triggered when working from the interactive REPL, even a minimal running thread can trigger it. This commit adds a test case that triggers it in a different way (polling stdin from a thread). Fix is to add a port-level macro that indicates whether the TinyUSB task can run. Closes micropython#15390. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Calls to run TinyUSB from other threads now schedule it to run on the main thread, instead. Depends on the parent commit which changes the scheduler to only run on the main thread. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
MicroPython v1.24.0-preview.201.g269a0e0e1 on 2024-08-09; Raspberry Pi Pico2 with RP2350 Console output from Thonny:
From running this:
Secondary issue - uncomment line 66 STOP = True - thread does not terminate. |
@adrianblakey I think the PR linked above will fix this when it's merged.
This looks like it should work (in cases where the |
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
If GIL is disabled then there's threat of a race condition if some other code specifically requests USB processing (i.e. to unblock stdio), while a scheduled TinyUSB callback is already running on another thread. Relies on the change in the parent commit, where scheduler is restricted to main thread if GIL is disabled. Fixes micropython#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when using _thread module and USB serial I/O. Adds a unit test for stdin functioning correctly in threads (fails on rp2 port without this fix). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Port, board and/or hardware
Raspberry Pi Pico
MicroPython version
MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico with RP2040
Reproduction
Expected behaviour
I found that this problem does not exist in version 1.22.2
Observed behaviour
My previous program didn't work after I updated the firmware. I was sure the program would work, so I changed the firmware to 1.22.2 and it worked.I found when the "while True" in "_thread.start_new_thread" , this problem must occur. I guess it is caused by USB-related changes.
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree
The text was updated successfully, but these errors were encountered: