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:
parent
d5db8f0461
commit
32c65ad455
4 changed files with 33 additions and 14 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue