ports: Implement simple write polling for stdout.

This is a best-effort implementation of write polling.  It's difficult to
do correctly because if there are multiple output streams (eg UART and USB
CDC) then some may not be writeable while others are.  A full solution
should also have a return value from mp_hal_stdout_tx_strn(), returning the
number of bytes written to the stream(s).  That's also hard to define.

The renesas-ra and stm32 ports already implement a similar best-effort
mechanism for write polling.

Fixes issue #11026.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2023-03-22 00:14:46 +11:00
parent 6c76248960
commit 38e7b842c6
10 changed files with 39 additions and 0 deletions

View File

@ -88,6 +88,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
if ((poll_flags & MP_STREAM_POLL_RD) && stdin_ringbuf.iget != stdin_ringbuf.iput) {
ret |= MP_STREAM_POLL_RD;
}
if (poll_flags & MP_STREAM_POLL_WR) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}

View File

@ -62,6 +62,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
if ((poll_flags & MP_STREAM_POLL_RD) && stdin_ringbuf.iget != stdin_ringbuf.iput) {
ret |= MP_STREAM_POLL_RD;
}
if (poll_flags & MP_STREAM_POLL_WR) {
ret |= mp_uos_dupterm_poll(poll_flags);
}
return ret;
}

View File

@ -86,6 +86,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) && tud_cdc_connected() && tud_cdc_write_available() > 0) {
ret |= MP_STREAM_POLL_WR;
}
#if MICROPY_PY_OS_DUPTERM
ret |= mp_uos_dupterm_poll(poll_flags);
#endif

View File

@ -164,6 +164,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
&& !isBufferEmpty(mp_rx_ring_buffer)) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) && ble_uart_enabled()) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}
#endif

View File

@ -213,6 +213,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
ret |= MP_STREAM_POLL_RD;
}
}
if (poll_flags & MP_STREAM_POLL_WR) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}

View File

@ -179,6 +179,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
&& uart_rx_any(MP_STATE_PORT(board_stdio_uart))) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) && MP_STATE_PORT(board_stdio_uart) != NULL) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}

View File

@ -57,6 +57,9 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
if ((poll_flags & MP_STREAM_POLL_RD) && uart_rx_any()) {
ret |= MP_STREAM_POLL_RD;
}
if (poll_flags & MP_STREAM_POLL_WR) {
ret |= MP_STREAM_POLL_WR;
}
return ret;
}

View File

@ -98,6 +98,15 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) {
ret |= MP_STREAM_POLL_RD;
}
if (poll_flags & MP_STREAM_POLL_WR) {
#if MICROPY_HW_ENABLE_UART_REPL
ret |= MP_STREAM_POLL_WR;
#else
if (tud_cdc_connected() && tud_cdc_write_available() > 0) {
ret |= MP_STREAM_POLL_WR;
}
#endif
}
#endif
#if MICROPY_PY_OS_DUPTERM
ret |= mp_uos_dupterm_poll(poll_flags);

View File

@ -162,6 +162,10 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
ret |= MP_STREAM_POLL_RD;
}
if ((poll_flags & MP_STREAM_POLL_WR) && tud_cdc_connected() && tud_cdc_write_available() > 0) {
ret |= MP_STREAM_POLL_WR;
}
#if MICROPY_PY_OS_DUPTERM
ret |= mp_uos_dupterm_poll(poll_flags);
#endif

View File

@ -32,6 +32,11 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
ret |= MP_STREAM_POLL_RD;
}
}
if (poll_flags & MP_STREAM_POLL_WR) {
if (MP_STATE_PORT(pyb_stdio_uart) != NULL || usb_vcp_is_enabled()) {
ret |= MP_STREAM_POLL_WR;
}
}
return ret;
}