nrf: Only process interrupt chars on UARTs used for REPL.

This commit adds an `attached_to_repl` property to each UART, and makes
sure that property is correctly set/unset when the UART is attached to or
detached from the REPL.

That property is then used to make sure incoming characters on the UART are
only checked for the interrupt character if the UART is attached to the
REPL.  Otherwise a board without REPL on UART can have its code interrupted
if ctrl-C is received on the UART.

Also, put incoming UART characters on to `stdin_ringbuf` instead of the
UARTs ring buffer (the former is much larger than the latter).

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2025-04-22 11:51:35 +10:00
parent d5db8f0461
commit 32c65ad455
4 changed files with 33 additions and 14 deletions

View file

@ -40,6 +40,7 @@
#include "py/gc.h"
#include "py/compile.h"
#include "py/persistentcode.h"
#include "extmod/misc.h"
#include "extmod/modmachine.h"
#include "shared/runtime/pyexec.h"
#include "readline.h"
@ -172,7 +173,8 @@ soft_reset:
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL),
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL_BAUD),
};
MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args);
mp_obj_t uart = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args);
mp_os_dupterm_obj.fun.var(1, &uart);
}
#endif

View file

@ -104,6 +104,7 @@ typedef struct _machine_uart_obj_t {
uint16_t timeout_char; // timeout waiting between chars (in ms)
uint8_t uart_id;
bool initialized; // static flag. Initialized to False
bool attached_to_repl;
#if MICROPY_PY_MACHINE_UART_IRQ
uint16_t mp_irq_trigger; // user IRQ trigger mask
uint16_t mp_irq_flags; // user IRQ active IRQ flags
@ -118,6 +119,13 @@ static machine_uart_obj_t machine_uart_obj[] = {
};
void uart_init0(void) {
for (int i = 0; i < MP_ARRAY_SIZE(machine_uart_obj); i++) {
machine_uart_obj[i].attached_to_repl = false;
}
}
void uart_attach_to_repl(machine_uart_obj_t *self, bool attached) {
self->attached_to_repl = attached;
}
static int uart_find(mp_obj_t id) {
@ -137,14 +145,16 @@ static void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context
if (p_event->type == NRFX_UART_EVT_RX_DONE) {
nrfx_uart_rx(self->p_uart, &self->buf.rx_buf[0], 1);
int chr = self->buf.rx_buf[0];
#if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION
if (chr == mp_interrupt_char) {
self->buf.rx_ringbuf.iget = 0;
self->buf.rx_ringbuf.iput = 0;
mp_sched_keyboard_interrupt();
} else
#endif
{
if (self->attached_to_repl) {
#if MICROPY_KBD_EXCEPTION
if (chr == mp_interrupt_char) {
mp_sched_keyboard_interrupt();
} else
#endif
{
ringbuf_put((ringbuf_t *)&stdin_ringbuf, chr);
}
} else {
ringbuf_put((ringbuf_t *)&self->buf.rx_ringbuf, chr);
}
#if MICROPY_PY_MACHINE_UART_IRQ

View file

@ -34,8 +34,7 @@
typedef struct _machine_uart_obj_t machine_uart_obj_t;
void uart_init0(void);
void uart_deinit(void);
void uart_irq_handler(mp_uint_t uart_id);
void uart_attach_to_repl(machine_uart_obj_t *self, bool attached);
bool uart_rx_any(machine_uart_obj_t *uart_obj);
int uart_rx_char(machine_uart_obj_t *uart_obj);

View file

@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "extmod/modmachine.h"
#include "drivers/rng.h"
#include "modules/machine/uart.h"
#if MICROPY_PY_OS_URANDOM
// Return a bytes object with n random bytes, generated by the hardware random number generator.
@ -46,10 +47,17 @@ static MP_DEFINE_CONST_FUN_OBJ_1(mp_os_urandom_obj, mp_os_urandom);
#endif
#if MICROPY_PY_OS_DUPTERM
// TODO should accept any object with read/write methods.
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
if (!(stream_attached == mp_const_none || mp_obj_get_type(stream_attached) == &machine_uart_type)) {
mp_raise_ValueError(MP_ERROR_TEXT("need a UART object"));
#if MICROPY_PY_MACHINE_UART
if (mp_obj_get_type(stream_detached) == &machine_uart_type) {
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false);
}
#endif
#if MICROPY_PY_MACHINE_UART
if (mp_obj_get_type(stream_attached) == &machine_uart_type) {
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true);
}
#endif
}
#endif // MICROPY_PY_OS_DUPTERM