diff options
author | Damien George <damien.p.george@gmail.com> | 2015-05-06 00:02:58 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-05-06 00:02:58 +0100 |
commit | c98c128fe885e539ecd73843756340f8950115c8 (patch) | |
tree | 72030c7c91a12aea609edced0a233e1aa7d9c8cf | |
parent | 367d4d10983c0047d2f1c91ebe44a45e5f2bbf65 (diff) | |
download | micropython-c98c128fe885e539ecd73843756340f8950115c8.tar.gz micropython-c98c128fe885e539ecd73843756340f8950115c8.zip |
pyexec: Make raw REPL work with event-driven version of pyexec.
esp8266 port now has working raw and friendly REPL, as well as working
soft reset (CTRL-D at REPL, or raise SystemExit).
tools/pyboard.py now works with esp8266 port.
-rw-r--r-- | esp8266/main.c | 34 | ||||
-rw-r--r-- | esp8266/uart.c | 10 | ||||
-rw-r--r-- | minimal/main.c | 6 | ||||
-rw-r--r-- | stmhal/pyexec.c | 218 | ||||
-rw-r--r-- | stmhal/pyexec.h | 4 |
5 files changed, 165 insertions, 107 deletions
diff --git a/esp8266/main.c b/esp8266/main.c index b6024f3c57..a3878c0e75 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -39,8 +39,7 @@ STATIC char heap[16384]; -void user_init(void) { -soft_reset: +STATIC void mp_reset(void) { mp_stack_set_limit(10240); mp_hal_init(); gc_init(heap, heap + sizeof(heap)); @@ -48,29 +47,20 @@ soft_reset: mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); +} - printf("\n"); +void soft_reset(void) { + mp_hal_stdout_tx_str("PYB: soft reset\r\n"); + mp_hal_udelay(10000); // allow UART to flush output + mp_reset(); + pyexec_event_repl_init(); +} -#if MICROPY_REPL_EVENT_DRIVEN - pyexec_friendly_repl_init(); +void user_init(void) { + mp_reset(); + mp_hal_stdout_tx_str("\r\n"); + pyexec_event_repl_init(); uart_task_init(); - return; - goto soft_reset; -#else - for (;;) { - if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { - if (pyexec_raw_repl() != 0) { - break; - } - } else { - if (pyexec_friendly_repl() != 0) { - break; - } - } - } - - goto soft_reset; -#endif } mp_lexer_t *mp_lexer_new_from_file(const char *filename) { diff --git a/esp8266/uart.c b/esp8266/uart.c index 6087668a70..87bbb7c92e 100644 --- a/esp8266/uart.c +++ b/esp8266/uart.c @@ -200,10 +200,16 @@ void ICACHE_FLASH_ATTR uart_reattach() { // Task-based UART interface -int pyexec_friendly_repl_process_char(int c); +#include "py/obj.h" +#include "stmhal/pyexec.h" + +void soft_reset(void); void uart_task_handler(os_event_t *evt) { - pyexec_friendly_repl_process_char(evt->par); + int ret = pyexec_event_repl_process_char(evt->par); + if (ret & PYEXEC_FORCED_EXIT) { + soft_reset(); + } } void uart_task_init() { diff --git a/minimal/main.c b/minimal/main.c index 29b5af1af7..f6041267a2 100644 --- a/minimal/main.c +++ b/minimal/main.c @@ -41,10 +41,10 @@ int main(int argc, char **argv) { #endif mp_init(); #if MICROPY_REPL_EVENT_DRIVEN - pyexec_friendly_repl_init(); + pyexec_event_repl_init(); for (;;) { - int c = stdin_rx_chr(); - if (pyexec_friendly_repl_process_char(c)) { + int c = mp_hal_stdin_rx_chr(); + if (pyexec_event_repl_process_char(c)) { break; } } diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index 1a121ce3e5..aa7e353905 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -118,83 +118,81 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki return ret; } -int pyexec_raw_repl(void) { - vstr_t line; - vstr_init(&line, 32); - -raw_repl_reset: - mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); - - for (;;) { - vstr_reset(&line); - mp_hal_stdout_tx_str(">"); - for (;;) { - int c = mp_hal_stdin_rx_chr(); - if (c == CHAR_CTRL_A) { - // reset raw REPL - goto raw_repl_reset; - } else if (c == CHAR_CTRL_B) { - // change to friendly REPL - mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&line); - pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; - return 0; - } else if (c == CHAR_CTRL_C) { - // clear line - vstr_reset(&line); - } else if (c == CHAR_CTRL_D) { - // input finished - break; - } else { - // let through any other raw 8-bit value - vstr_add_byte(&line, c); - } - } - - // indicate reception of command - mp_hal_stdout_tx_str("OK"); - - if (line.len == 0) { - // exit for a soft reset - mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&line); - return PYEXEC_FORCED_EXIT; - } - - mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); - if (lex == NULL) { - printf("\x04MemoryError\n\x04"); - } else { - int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); - if (ret & PYEXEC_FORCED_EXIT) { - return ret; - } - } - } -} - #if MICROPY_REPL_EVENT_DRIVEN -typedef struct _friendly_repl_t { +typedef struct _repl_t { + // XXX line holds a root pointer! vstr_t line; bool cont_line; -} friendly_repl_t; +} repl_t; + +repl_t repl; -friendly_repl_t repl; +STATIC int pyexec_raw_repl_process_char(int c); +STATIC int pyexec_friendly_repl_process_char(int c); -void pyexec_friendly_repl_init(void) { +void pyexec_event_repl_init(void) { vstr_init(&repl.line, 32); repl.cont_line = false; readline_init(&repl.line, ">>> "); + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + pyexec_raw_repl_process_char(CHAR_CTRL_A); + } else { + pyexec_friendly_repl_process_char(CHAR_CTRL_B); + } } -void pyexec_friendly_repl_reset(void) { +STATIC int pyexec_raw_repl_process_char(int c) { + if (c == CHAR_CTRL_A) { + // reset raw REPL + mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); + goto reset; + } else if (c == CHAR_CTRL_B) { + // change to friendly REPL + pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + repl.cont_line = false; + pyexec_friendly_repl_process_char(CHAR_CTRL_B); + return 0; + } else if (c == CHAR_CTRL_C) { + // clear line + vstr_reset(&repl.line); + return 0; + } else if (c == CHAR_CTRL_D) { + // input finished + } else { + // let through any other raw 8-bit value + vstr_add_byte(&repl.line, c); + return 0; + } + + // indicate reception of command + mp_hal_stdout_tx_str("OK"); + + if (repl.line.len == 0) { + // exit for a soft reset + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&repl.line); + return PYEXEC_FORCED_EXIT; + } + + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, repl.line.buf, repl.line.len, 0); + if (lex == NULL) { + mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04"); + } else { + int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); + if (ret & PYEXEC_FORCED_EXIT) { + return ret; + } + } + +reset: vstr_reset(&repl.line); - repl.cont_line = false; - readline_init(&repl.line, ">>> "); + mp_hal_stdout_tx_str(">"); + + return 0; } -int pyexec_friendly_repl_process_char(int c) { +STATIC int pyexec_friendly_repl_process_char(int c) { int ret = readline_process_char(c); if (!repl.cont_line) { @@ -203,12 +201,14 @@ int pyexec_friendly_repl_process_char(int c) { // change to raw REPL pyexec_mode_kind = PYEXEC_MODE_RAW_REPL; mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&repl.line); - return PYEXEC_SWITCH_MODE; + pyexec_raw_repl_process_char(CHAR_CTRL_A); + return 0; } else if (ret == CHAR_CTRL_B) { // reset friendly REPL mp_hal_stdout_tx_str("\r\n"); - goto friendly_repl_reset; + mp_hal_stdout_tx_str("Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n"); + mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); + goto input_restart; } else if (ret == CHAR_CTRL_C) { // break mp_hal_stdout_tx_str("\r\n"); @@ -218,8 +218,6 @@ int pyexec_friendly_repl_process_char(int c) { mp_hal_stdout_tx_str("\r\n"); vstr_clear(&repl.line); return PYEXEC_FORCED_EXIT; - } else if (vstr_len(&repl.line) == 0) { - //goto input_restart; } if (ret < 0) { @@ -238,13 +236,13 @@ int pyexec_friendly_repl_process_char(int c) { } else { if (ret == CHAR_CTRL_C) { - // cancel everything - mp_hal_stdout_tx_str("\r\n"); - repl.cont_line = false; - goto input_restart; + // cancel everything + mp_hal_stdout_tx_str("\r\n"); + repl.cont_line = false; + goto input_restart; } else if (ret == CHAR_CTRL_D) { - // stop entering compound statement - goto exec; + // stop entering compound statement + goto exec; } if (ret < 0) { @@ -268,14 +266,78 @@ exec: ; } } -friendly_repl_reset: // TODO input_restart: - pyexec_friendly_repl_reset(); + vstr_reset(&repl.line); + repl.cont_line = false; + readline_init(&repl.line, ">>> "); return 0; } } -#else //MICROPY_REPL_EVENT_DRIVEN +int pyexec_event_repl_process_char(int c) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + return pyexec_raw_repl_process_char(c); + } else { + return pyexec_friendly_repl_process_char(c); + } +} + +#else // MICROPY_REPL_EVENT_DRIVEN + +int pyexec_raw_repl(void) { + vstr_t line; + vstr_init(&line, 32); + +raw_repl_reset: + mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); + + for (;;) { + vstr_reset(&line); + mp_hal_stdout_tx_str(">"); + for (;;) { + int c = mp_hal_stdin_rx_chr(); + if (c == CHAR_CTRL_A) { + // reset raw REPL + goto raw_repl_reset; + } else if (c == CHAR_CTRL_B) { + // change to friendly REPL + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&line); + pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + return 0; + } else if (c == CHAR_CTRL_C) { + // clear line + vstr_reset(&line); + } else if (c == CHAR_CTRL_D) { + // input finished + break; + } else { + // let through any other raw 8-bit value + vstr_add_byte(&line, c); + } + } + + // indicate reception of command + mp_hal_stdout_tx_str("OK"); + + if (line.len == 0) { + // exit for a soft reset + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&line); + return PYEXEC_FORCED_EXIT; + } + + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); + if (lex == NULL) { + printf("\x04MemoryError\n\x04"); + } else { + int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); + if (ret & PYEXEC_FORCED_EXIT) { + return ret; + } + } + } +} int pyexec_friendly_repl(void) { vstr_t line; @@ -376,7 +438,7 @@ friendly_repl_reset: } } -#endif //MICROPY_REPL_EVENT_DRIVEN +#endif // MICROPY_REPL_EVENT_DRIVEN int pyexec_file(const char *filename) { mp_lexer_t *lex = mp_lexer_new_from_file(filename); diff --git a/stmhal/pyexec.h b/stmhal/pyexec.h index d01d505a78..0728b91333 100644 --- a/stmhal/pyexec.h +++ b/stmhal/pyexec.h @@ -37,7 +37,7 @@ extern pyexec_mode_kind_t pyexec_mode_kind; int pyexec_raw_repl(void); int pyexec_friendly_repl(void); int pyexec_file(const char *filename); -void pyexec_friendly_repl_init(void); -int pyexec_friendly_repl_process_char(int c); +void pyexec_event_repl_init(void); +int pyexec_event_repl_process_char(int c); MP_DECLARE_CONST_FUN_OBJ(pyb_set_repl_info_obj); |