esp8266: Implement input part of dupterm handling.

The idea is following: underlying interrupt-driven or push-style data source
signals that more data is available for dupterm processing via call to
mp_hal_signal_dupterm_input(). This triggers a task which pumps data between
actual dupterm object (which may perform additional processing on data from
low-level data source) and input ring buffer.
This commit is contained in:
Paul Sokolovsky 2016-03-31 19:49:55 +03:00
parent 61fa7c8152
commit 98af891610
3 changed files with 62 additions and 0 deletions

View File

@ -34,6 +34,7 @@
#include "py/obj.h"
#include "py/mpstate.h"
#include "extmod/misc.h"
#include "lib/utils/pyexec.h"
extern void ets_wdt_disable(void);
extern void wdt_feed(void);
@ -157,3 +158,59 @@ void __assert_func(const char *file, int line, const char *func, const char *exp
void mp_hal_signal_input(void) {
system_os_post(UART_TASK_ID, 0, 0);
}
static int call_dupterm_read(void) {
if (MP_STATE_PORT(term_obj) == NULL) {
return -1;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t read_m[3];
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
if (res == mp_const_none) {
return -2;
}
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
if (bufinfo.len == 0) {
mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
MP_STATE_PORT(term_obj) = NULL;
return -1;
}
nlr_pop();
return *(byte*)bufinfo.buf;
} else {
// Temporarily disable dupterm to avoid infinite recursion
mp_obj_t save_term = MP_STATE_PORT(term_obj);
MP_STATE_PORT(term_obj) = NULL;
mp_printf(&mp_plat_print, "dupterm: ");
mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
MP_STATE_PORT(term_obj) = save_term;
}
return -1;
}
STATIC void dupterm_task_handler(os_event_t *evt) {
while (1) {
int c = call_dupterm_read();
if (c < 0) {
break;
}
ringbuf_put(&input_buf, c);
}
mp_hal_signal_input();
}
STATIC os_event_t dupterm_evt_queue[4];
void dupterm_task_init() {
system_os_task(dupterm_task_handler, DUPTERM_TASK_ID, dupterm_evt_queue, MP_ARRAY_SIZE(dupterm_evt_queue));
}
void mp_hal_signal_dupterm_input(void) {
system_os_post(DUPTERM_TASK_ID, 0, 0);
}

View File

@ -36,6 +36,8 @@ extern const struct _mp_print_t mp_debug_print;
extern ringbuf_t input_buf;
// Call this after putting data to input_buf
void mp_hal_signal_input(void);
// Call this when data is available in dupterm object
void mp_hal_signal_dupterm_input(void);
void mp_hal_init(void);
void mp_hal_rtc_init(void);
@ -47,7 +49,9 @@ void mp_hal_set_interrupt_char(int c);
uint32_t mp_hal_get_cpu_freq(void);
#define UART_TASK_ID 0
#define DUPTERM_TASK_ID 1
void uart_task_init();
void dupterm_task_init();
void ets_event_poll(void);
#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); }

View File

@ -69,6 +69,7 @@ void init_done(void) {
mp_reset();
mp_hal_stdout_tx_str("\r\n");
pyexec_event_repl_init();
dupterm_task_init();
}
void user_init(void) {