diff --git a/bricks/_common_stm32/mphalport.c b/bricks/_common_stm32/mphalport.c index d2a2fc30c..ae54727a0 100644 --- a/bricks/_common_stm32/mphalport.c +++ b/bricks/_common_stm32/mphalport.c @@ -88,13 +88,17 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t org_len = len; + while (len--) { while (!(USART6->SR & USART_SR_TXE)) { MICROPY_VM_HOOK_LOOP } USART6->DR = *str++; } + + return org_len; } void mp_hal_stdout_tx_flush(void) { @@ -127,7 +131,9 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t org_len = len; + while (len) { uint32_t size = len; pbio_error_t err = pbsys_bluetooth_tx((const uint8_t *)str, &size); @@ -141,11 +147,13 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { if (err != PBIO_ERROR_AGAIN) { // Ignoring error for now. This means stdout lost if Bluetooth is // disconnected. - return; + return org_len - len; } MICROPY_EVENT_POLL_HOOK } + + return org_len; } void mp_hal_stdout_tx_flush(void) { diff --git a/bricks/ev3dev/ev3dev_mphal.c b/bricks/ev3dev/ev3dev_mphal.c index 6dd1aa25a..e4ac74983 100644 --- a/bricks/ev3dev/ev3dev_mphal.c +++ b/bricks/ev3dev/ev3dev_mphal.c @@ -109,11 +109,26 @@ int mp_hal_stdin_rx_chr(void) { return c; } -void mp_hal_stdout_tx_strn(const char *str, size_t len) { - MP_THREAD_GIL_EXIT(); - int ret = write(STDOUT_FILENO, str, len); - MP_THREAD_GIL_ENTER(); - (void)ret; // to suppress compiler warning +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t remaining = len; + while (remaining > 0) { + MP_THREAD_GIL_EXIT(); + ssize_t ret = write(STDOUT_FILENO, str, remaining); + MP_THREAD_GIL_ENTER(); + if (ret < 0) { + if (errno == EINTR) { + continue; + } + return len - remaining; + } + /* Defensive check: POSIX guarantees ret <= remaining, but guard against non-compliant implementations. */ + if ((size_t)ret > remaining) { + return len; + } + str += ret; + remaining -= (size_t)ret; + } + return len; } // cooked is same as uncooked because the terminal does some postprocessing diff --git a/bricks/ev3rt/mphalport.c b/bricks/ev3rt/mphalport.c index 7f1dfab2d..14602fe92 100644 --- a/bricks/ev3rt/mphalport.c +++ b/bricks/ev3rt/mphalport.c @@ -75,11 +75,14 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { uint32_t in_waiting; if (bluetooth_is_connected(&in_waiting)) { serial_wri_dat(EV3_SERIAL_BT, str, len); + return len; } + + return 0; } void mp_hal_stdout_tx_flush(void) { diff --git a/bricks/nxt/mphalport.c b/bricks/nxt/mphalport.c index dafb13453..369620cf8 100644 --- a/bricks/nxt/mphalport.c +++ b/bricks/nxt/mphalport.c @@ -85,17 +85,20 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { // Nothing to do if disconnected or empty data if (!nx_bt_stream_opened() || len == 0) { - return; + return 0; } + size_t org_len = len; nx_bt_stream_write((uint8_t *)str, len); while (!nx_bt_stream_data_written()) { MICROPY_EVENT_POLL_HOOK; } + + return org_len; } void mp_hal_stdout_tx_flush(void) { diff --git a/bricks/primehub_spike-rt/mphalport.c b/bricks/primehub_spike-rt/mphalport.c index 5f22f97d6..26104a81f 100644 --- a/bricks/primehub_spike-rt/mphalport.c +++ b/bricks/primehub_spike-rt/mphalport.c @@ -58,14 +58,14 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -//void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t org_len = len; extern void tPutLogTarget_ePutLog_putChar(char c); while (len--) { tPutLogTarget_ePutLog_putChar(*str++); } // serial_wri_dat(TASK_PORTID, str, len) - return 0; + return org_len; } #else // !PYBRICKS_HUB_DEBUG @@ -94,7 +94,9 @@ int mp_hal_stdin_rx_chr(void) { } // Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t org_len = len; + while (len) { uint32_t size = len; pbio_error_t err = pbsys_bluetooth_tx((const uint8_t *)str, &size); @@ -108,11 +110,13 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { if (err != PBIO_ERROR_AGAIN) { // Ignoring error for now. This means stdout lost if Bluetooth is // disconnected. - return; + return org_len - len; } MICROPY_EVENT_POLL_HOOK } + + return org_len; } #endif // PYBRICKS_HUB_DEBUG