Skip to content

Commit c98c128

Browse files
committed
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.
1 parent 367d4d1 commit c98c128

File tree

5 files changed

+165
-107
lines changed

5 files changed

+165
-107
lines changed

esp8266/main.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,38 +39,28 @@
3939

4040
STATIC char heap[16384];
4141

42-
void user_init(void) {
43-
soft_reset:
42+
STATIC void mp_reset(void) {
4443
mp_stack_set_limit(10240);
4544
mp_hal_init();
4645
gc_init(heap, heap + sizeof(heap));
4746
gc_collect_init();
4847
mp_init();
4948
mp_obj_list_init(mp_sys_path, 0);
5049
mp_obj_list_init(mp_sys_argv, 0);
50+
}
5151

52-
printf("\n");
52+
void soft_reset(void) {
53+
mp_hal_stdout_tx_str("PYB: soft reset\r\n");
54+
mp_hal_udelay(10000); // allow UART to flush output
55+
mp_reset();
56+
pyexec_event_repl_init();
57+
}
5358

54-
#if MICROPY_REPL_EVENT_DRIVEN
55-
pyexec_friendly_repl_init();
59+
void user_init(void) {
60+
mp_reset();
61+
mp_hal_stdout_tx_str("\r\n");
62+
pyexec_event_repl_init();
5663
uart_task_init();
57-
return;
58-
goto soft_reset;
59-
#else
60-
for (;;) {
61-
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
62-
if (pyexec_raw_repl() != 0) {
63-
break;
64-
}
65-
} else {
66-
if (pyexec_friendly_repl() != 0) {
67-
break;
68-
}
69-
}
70-
}
71-
72-
goto soft_reset;
73-
#endif
7464
}
7565

7666
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {

esp8266/uart.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,16 @@ void ICACHE_FLASH_ATTR uart_reattach() {
200200

201201
// Task-based UART interface
202202

203-
int pyexec_friendly_repl_process_char(int c);
203+
#include "py/obj.h"
204+
#include "stmhal/pyexec.h"
205+
206+
void soft_reset(void);
204207

205208
void uart_task_handler(os_event_t *evt) {
206-
pyexec_friendly_repl_process_char(evt->par);
209+
int ret = pyexec_event_repl_process_char(evt->par);
210+
if (ret & PYEXEC_FORCED_EXIT) {
211+
soft_reset();
212+
}
207213
}
208214

209215
void uart_task_init() {

minimal/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ int main(int argc, char **argv) {
4141
#endif
4242
mp_init();
4343
#if MICROPY_REPL_EVENT_DRIVEN
44-
pyexec_friendly_repl_init();
44+
pyexec_event_repl_init();
4545
for (;;) {
46-
int c = stdin_rx_chr();
47-
if (pyexec_friendly_repl_process_char(c)) {
46+
int c = mp_hal_stdin_rx_chr();
47+
if (pyexec_event_repl_process_char(c)) {
4848
break;
4949
}
5050
}

stmhal/pyexec.c

Lines changed: 140 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -118,83 +118,81 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki
118118
return ret;
119119
}
120120

121-
int pyexec_raw_repl(void) {
122-
vstr_t line;
123-
vstr_init(&line, 32);
124-
125-
raw_repl_reset:
126-
mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
127-
128-
for (;;) {
129-
vstr_reset(&line);
130-
mp_hal_stdout_tx_str(">");
131-
for (;;) {
132-
int c = mp_hal_stdin_rx_chr();
133-
if (c == CHAR_CTRL_A) {
134-
// reset raw REPL
135-
goto raw_repl_reset;
136-
} else if (c == CHAR_CTRL_B) {
137-
// change to friendly REPL
138-
mp_hal_stdout_tx_str("\r\n");
139-
vstr_clear(&line);
140-
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
141-
return 0;
142-
} else if (c == CHAR_CTRL_C) {
143-
// clear line
144-
vstr_reset(&line);
145-
} else if (c == CHAR_CTRL_D) {
146-
// input finished
147-
break;
148-
} else {
149-
// let through any other raw 8-bit value
150-
vstr_add_byte(&line, c);
151-
}
152-
}
153-
154-
// indicate reception of command
155-
mp_hal_stdout_tx_str("OK");
156-
157-
if (line.len == 0) {
158-
// exit for a soft reset
159-
mp_hal_stdout_tx_str("\r\n");
160-
vstr_clear(&line);
161-
return PYEXEC_FORCED_EXIT;
162-
}
163-
164-
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
165-
if (lex == NULL) {
166-
printf("\x04MemoryError\n\x04");
167-
} else {
168-
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
169-
if (ret & PYEXEC_FORCED_EXIT) {
170-
return ret;
171-
}
172-
}
173-
}
174-
}
175-
176121
#if MICROPY_REPL_EVENT_DRIVEN
177122

178-
typedef struct _friendly_repl_t {
123+
typedef struct _repl_t {
124+
// XXX line holds a root pointer!
179125
vstr_t line;
180126
bool cont_line;
181-
} friendly_repl_t;
127+
} repl_t;
128+
129+
repl_t repl;
182130

183-
friendly_repl_t repl;
131+
STATIC int pyexec_raw_repl_process_char(int c);
132+
STATIC int pyexec_friendly_repl_process_char(int c);
184133

185-
void pyexec_friendly_repl_init(void) {
134+
void pyexec_event_repl_init(void) {
186135
vstr_init(&repl.line, 32);
187136
repl.cont_line = false;
188137
readline_init(&repl.line, ">>> ");
138+
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
139+
pyexec_raw_repl_process_char(CHAR_CTRL_A);
140+
} else {
141+
pyexec_friendly_repl_process_char(CHAR_CTRL_B);
142+
}
189143
}
190144

191-
void pyexec_friendly_repl_reset(void) {
145+
STATIC int pyexec_raw_repl_process_char(int c) {
146+
if (c == CHAR_CTRL_A) {
147+
// reset raw REPL
148+
mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
149+
goto reset;
150+
} else if (c == CHAR_CTRL_B) {
151+
// change to friendly REPL
152+
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
153+
repl.cont_line = false;
154+
pyexec_friendly_repl_process_char(CHAR_CTRL_B);
155+
return 0;
156+
} else if (c == CHAR_CTRL_C) {
157+
// clear line
158+
vstr_reset(&repl.line);
159+
return 0;
160+
} else if (c == CHAR_CTRL_D) {
161+
// input finished
162+
} else {
163+
// let through any other raw 8-bit value
164+
vstr_add_byte(&repl.line, c);
165+
return 0;
166+
}
167+
168+
// indicate reception of command
169+
mp_hal_stdout_tx_str("OK");
170+
171+
if (repl.line.len == 0) {
172+
// exit for a soft reset
173+
mp_hal_stdout_tx_str("\r\n");
174+
vstr_clear(&repl.line);
175+
return PYEXEC_FORCED_EXIT;
176+
}
177+
178+
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, repl.line.buf, repl.line.len, 0);
179+
if (lex == NULL) {
180+
mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
181+
} else {
182+
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
183+
if (ret & PYEXEC_FORCED_EXIT) {
184+
return ret;
185+
}
186+
}
187+
188+
reset:
192189
vstr_reset(&repl.line);
193-
repl.cont_line = false;
194-
readline_init(&repl.line, ">>> ");
190+
mp_hal_stdout_tx_str(">");
191+
192+
return 0;
195193
}
196194

197-
int pyexec_friendly_repl_process_char(int c) {
195+
STATIC int pyexec_friendly_repl_process_char(int c) {
198196
int ret = readline_process_char(c);
199197

200198
if (!repl.cont_line) {
@@ -203,12 +201,14 @@ int pyexec_friendly_repl_process_char(int c) {
203201
// change to raw REPL
204202
pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
205203
mp_hal_stdout_tx_str("\r\n");
206-
vstr_clear(&repl.line);
207-
return PYEXEC_SWITCH_MODE;
204+
pyexec_raw_repl_process_char(CHAR_CTRL_A);
205+
return 0;
208206
} else if (ret == CHAR_CTRL_B) {
209207
// reset friendly REPL
210208
mp_hal_stdout_tx_str("\r\n");
211-
goto friendly_repl_reset;
209+
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");
210+
mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
211+
goto input_restart;
212212
} else if (ret == CHAR_CTRL_C) {
213213
// break
214214
mp_hal_stdout_tx_str("\r\n");
@@ -218,8 +218,6 @@ int pyexec_friendly_repl_process_char(int c) {
218218
mp_hal_stdout_tx_str("\r\n");
219219
vstr_clear(&repl.line);
220220
return PYEXEC_FORCED_EXIT;
221-
} else if (vstr_len(&repl.line) == 0) {
222-
//goto input_restart;
223221
}
224222

225223
if (ret < 0) {
@@ -238,13 +236,13 @@ int pyexec_friendly_repl_process_char(int c) {
238236
} else {
239237

240238
if (ret == CHAR_CTRL_C) {
241-
// cancel everything
242-
mp_hal_stdout_tx_str("\r\n");
243-
repl.cont_line = false;
244-
goto input_restart;
239+
// cancel everything
240+
mp_hal_stdout_tx_str("\r\n");
241+
repl.cont_line = false;
242+
goto input_restart;
245243
} else if (ret == CHAR_CTRL_D) {
246-
// stop entering compound statement
247-
goto exec;
244+
// stop entering compound statement
245+
goto exec;
248246
}
249247

250248
if (ret < 0) {
@@ -268,14 +266,78 @@ exec: ;
268266
}
269267
}
270268

271-
friendly_repl_reset: // TODO
272269
input_restart:
273-
pyexec_friendly_repl_reset();
270+
vstr_reset(&repl.line);
271+
repl.cont_line = false;
272+
readline_init(&repl.line, ">>> ");
274273
return 0;
275274
}
276275
}
277276

278-
#else //MICROPY_REPL_EVENT_DRIVEN
277+
int pyexec_event_repl_process_char(int c) {
278+
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
279+
return pyexec_raw_repl_process_char(c);
280+
} else {
281+
return pyexec_friendly_repl_process_char(c);
282+
}
283+
}
284+
285+
#else // MICROPY_REPL_EVENT_DRIVEN
286+
287+
int pyexec_raw_repl(void) {
288+
vstr_t line;
289+
vstr_init(&line, 32);
290+
291+
raw_repl_reset:
292+
mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
293+
294+
for (;;) {
295+
vstr_reset(&line);
296+
mp_hal_stdout_tx_str(">");
297+
for (;;) {
298+
int c = mp_hal_stdin_rx_chr();
299+
if (c == CHAR_CTRL_A) {
300+
// reset raw REPL
301+
goto raw_repl_reset;
302+
} else if (c == CHAR_CTRL_B) {
303+
// change to friendly REPL
304+
mp_hal_stdout_tx_str("\r\n");
305+
vstr_clear(&line);
306+
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
307+
return 0;
308+
} else if (c == CHAR_CTRL_C) {
309+
// clear line
310+
vstr_reset(&line);
311+
} else if (c == CHAR_CTRL_D) {
312+
// input finished
313+
break;
314+
} else {
315+
// let through any other raw 8-bit value
316+
vstr_add_byte(&line, c);
317+
}
318+
}
319+
320+
// indicate reception of command
321+
mp_hal_stdout_tx_str("OK");
322+
323+
if (line.len == 0) {
324+
// exit for a soft reset
325+
mp_hal_stdout_tx_str("\r\n");
326+
vstr_clear(&line);
327+
return PYEXEC_FORCED_EXIT;
328+
}
329+
330+
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
331+
if (lex == NULL) {
332+
printf("\x04MemoryError\n\x04");
333+
} else {
334+
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
335+
if (ret & PYEXEC_FORCED_EXIT) {
336+
return ret;
337+
}
338+
}
339+
}
340+
}
279341

280342
int pyexec_friendly_repl(void) {
281343
vstr_t line;
@@ -376,7 +438,7 @@ int pyexec_friendly_repl(void) {
376438
}
377439
}
378440

379-
#endif //MICROPY_REPL_EVENT_DRIVEN
441+
#endif // MICROPY_REPL_EVENT_DRIVEN
380442

381443
int pyexec_file(const char *filename) {
382444
mp_lexer_t *lex = mp_lexer_new_from_file(filename);

stmhal/pyexec.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extern pyexec_mode_kind_t pyexec_mode_kind;
3737
int pyexec_raw_repl(void);
3838
int pyexec_friendly_repl(void);
3939
int pyexec_file(const char *filename);
40-
void pyexec_friendly_repl_init(void);
41-
int pyexec_friendly_repl_process_char(int c);
40+
void pyexec_event_repl_init(void);
41+
int pyexec_event_repl_process_char(int c);
4242

4343
MP_DECLARE_CONST_FUN_OBJ(pyb_set_repl_info_obj);

0 commit comments

Comments
 (0)