Skip to content

Commit

Permalink
rp2/mphalport: Run TinyUSB stack while waiting for CDC input/output.
Browse files Browse the repository at this point in the history
The recent change in bcbdee2 means that
TinyUSB can no longer be run from within a soft (or hard) IRQ handler, ie
when the scheduler is locked.  That means that Python code that calls
`print(...)` from within a scheduled function may block indefinitely if the
USB CDC buffers are full.

This commit fixes that problem by explicitly running the TinyUSB stack when
waiting within stdio tx/rx functions.

Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
dpgeorge committed Nov 9, 2023
1 parent d46dc5e commit a00c9d5
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions ports/rp2/mphalport.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "extmod/misc.h"
#include "shared/runtime/interrupt_char.h"
#include "shared/timeutils/timeutils.h"
#include "shared/tinyusb/mp_usbd.h"
#include "tusb.h"
#include "uart.h"
#include "hardware/rtc.h"
Expand All @@ -54,6 +55,19 @@ ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) };

#endif

#if MICROPY_HW_USB_CDC
// Explicitly run the USB stack in case the scheduler is locked (eg we are in an
// interrupt handler) and there is in/out data pending on the USB CDC interface.
#define MICROPY_EVENT_POLL_HOOK_WITH_USB \
do { \
MICROPY_EVENT_POLL_HOOK; \
mp_usbd_task(); \
} while (0)

#else
#define MICROPY_EVENT_POLL_HOOK_WITH_USB MICROPY_EVENT_POLL_HOOK
#endif

#if MICROPY_HW_USB_CDC

uint8_t cdc_itf_pending; // keep track of cdc interfaces which need attention to poll
Expand Down Expand Up @@ -135,7 +149,7 @@ int mp_hal_stdin_rx_chr(void) {
return dupterm_c;
}
#endif
MICROPY_EVENT_POLL_HOOK
MICROPY_EVENT_POLL_HOOK_WITH_USB;
}
}

Expand All @@ -155,7 +169,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
int timeout = 0;
// Wait with a max of USC_CDC_TIMEOUT ms
while (n > tud_cdc_write_available() && timeout++ < MICROPY_HW_USB_CDC_TX_TIMEOUT) {
MICROPY_EVENT_POLL_HOOK
MICROPY_EVENT_POLL_HOOK_WITH_USB;
}
if (timeout >= MICROPY_HW_USB_CDC_TX_TIMEOUT) {
break;
Expand Down

0 comments on commit a00c9d5

Please sign in to comment.