Skip to content

Commit 152568b

Browse files
committed
NLR and Python exceptions work on the board.
1 parent c9f9197 commit 152568b

4 files changed

Lines changed: 179 additions & 25 deletions

File tree

py/nlr.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
#include <limits.h>
55

6-
#ifndef __WORDSIZE
7-
#error __WORDSIZE needs to be defined
8-
#endif
6+
//#ifndef __WORDSIZE
7+
//#error __WORDSIZE needs to be defined
8+
//#endif
99

1010
typedef struct _nlr_buf_t nlr_buf_t;
1111
struct _nlr_buf_t {
@@ -17,7 +17,9 @@ struct _nlr_buf_t {
1717
#elif __WORDSIZE == 64
1818
void *regs[8];
1919
#else
20-
#error Unsupported __WORDSIZE
20+
// hack for thumb
21+
void *regs[10];
22+
//#error Unsupported __WORDSIZE
2123
#endif
2224
};
2325

py/nlrthumb.s

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
@ thumb callee save: bx, bp, sp, r12, r14, r14, r15
2+
3+
.syntax unified
4+
.cpu cortex-m4
5+
.thumb
6+
.text
7+
.align 2
8+
9+
@ uint nlr_push(r0=nlr_buf_t *nlr)
10+
.global nlr_push
11+
.thumb
12+
.thumb_func
13+
.type nlr_push, %function
14+
nlr_push:
15+
str lr, [r0, #8] @ store lr into nlr_buf
16+
str r4, [r0, #12] @ store r4 into nlr_buf
17+
str r5, [r0, #16] @ store r5 into nlr_buf
18+
str r6, [r0, #20] @ store r6 into nlr_buf
19+
str r7, [r0, #24] @ store r7 into nlr_buf
20+
str r8, [r0, #28] @ store r8 into nlr_buf
21+
str r9, [r0, #32] @ store r9 into nlr_buf
22+
str r10, [r0, #36] @ store r10 into nlr_buf
23+
str r11, [r0, #40] @ store r11 into nlr_buf
24+
str r13, [r0, #44] @ store r13=sp into nlr_buf
25+
26+
ldr r3, .L2 @ load addr of nlr_top
27+
ldr r2, [r3] @ load nlr_top
28+
str r2, [r0] @ store nlr_top into nlr_buf
29+
str r0, [r3] @ store nlr_buf into nlr_top (to link list)
30+
31+
movs r0, #0 @ return 0, normal return
32+
bx lr @ return
33+
.align 2
34+
.L2:
35+
.word .LANCHOR0
36+
.size nlr_push, .-nlr_push
37+
38+
@ void nlr_pop()
39+
.global nlr_pop
40+
.thumb
41+
.thumb_func
42+
.type nlr_pop, %function
43+
nlr_pop:
44+
ldr r3, .L5 @ load addr of nlr_top
45+
ldr r2, [r3] @ load nlr_top
46+
ldr r2, [r2] @ load prev nlr_buf
47+
str r2, [r3] @ store prev nlr_buf to nlr_top (to unlink list)
48+
bx lr @ return
49+
.align 2
50+
.L5:
51+
.word .LANCHOR0
52+
.size nlr_pop, .-nlr_pop
53+
54+
@ void nlr_jump(r0=uint val)
55+
.global nlr_jump
56+
.thumb
57+
.thumb_func
58+
.type nlr_jump, %function
59+
nlr_jump:
60+
ldr r3, .L2 @ load addr of nlr_top
61+
ldr r2, [r3] @ load nlr_top
62+
str r0, [r2, #4] @ store return value
63+
ldr r0, [r2] @ load prev nlr_buf
64+
str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list)
65+
66+
ldr lr, [r2, #8] @ load lr from nlr_buf
67+
ldr r4, [r2, #12] @ load r4 from nlr_buf
68+
ldr r5, [r2, #16] @ load r5 from nlr_buf
69+
ldr r6, [r2, #20] @ load r6 from nlr_buf
70+
ldr r7, [r2, #24] @ load r7 from nlr_buf
71+
ldr r8, [r2, #28] @ load r8 from nlr_buf
72+
ldr r9, [r2, #32] @ load r9 from nlr_buf
73+
ldr r10, [r2, #36] @ load r10 from nlr_buf
74+
ldr r11, [r2, #40] @ load r11 from nlr_buf
75+
ldr r13, [r2, #44] @ load r13=sp from nlr_buf
76+
77+
movs r0, #1 @ return 1, non-local return
78+
bx lr @ return
79+
.align 2
80+
.L6:
81+
.word .LANCHOR0
82+
.size nlr_jump, .-nlr_jump
83+
84+
@ local variable nlr_top
85+
.bss
86+
.align 2
87+
.set .LANCHOR0,. + 0
88+
.type nlr_top, %object
89+
.size nlr_top, 4
90+
nlr_top:
91+
.space 4

stm/Makefile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ CC = arm-none-eabi-gcc
88
LD = arm-none-eabi-ld
99
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfloat-abi=hard -DSTM32F40XX -DHSE_VALUE=8000000
1010
CFLAGS = -I. -I$(PYSRC) -I$(FATFSSRC) -I$(STMSRC) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4)
11-
CFLAGS_PY = -DEMIT_ENABLE_THUMB
1211
LDFLAGS = --nostdlib -T stm32f405.ld
1312

1413
SRC_C = \
@@ -27,7 +26,8 @@ SRC_S = \
2726
startup_stm32f40xx.s \
2827

2928
PY_O = \
30-
# malloc.o \
29+
nlrthumb.o \
30+
malloc.o \
3131
qstr.o \
3232
misc.o \
3333
lexer.o \
@@ -109,15 +109,18 @@ $(BUILD)/%.o: $(FATFSSRC)/%.c
109109
$(BUILD)/%.o: $(STMSRC)/%.c
110110
$(CC) $(CFLAGS) -c -o $@ $<
111111

112+
$(BUILD)/%.o: $(PYSRC)/%.s
113+
$(AS) -c -o $@ $<
114+
112115
$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h
113-
$(CC) $(CFLAGS) $(CFLAGS_PY) -c -o $@ $<
116+
$(CC) $(CFLAGS) -c -o $@ $<
114117

115118
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
116-
$(CC) $(CFLAGS) $(CFLAGS_PY) -DN_THUMB -c -o $@ $<
119+
$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
117120

118121
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
119122
$(BUILD)/vm.o: $(PYSRC)/vm.c
120-
$(CC) $(CFLAGS) $(CFLAGS_PY) -O3 -c -o $@ $<
123+
$(CC) $(CFLAGS) -O3 -c -o $@ $<
121124

122125
$(BUILD)/parse.o: $(PYSRC)/grammar.h
123126
$(BUILD)/compile.o: $(PYSRC)/grammar.h

stm/main.c

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ void __fatal_error(const char *msg) {
418418
#include "compile.h"
419419
#include "runtime.h"
420420

421-
/*
422421
py_obj_t pyb_delay(py_obj_t count) {
423422
delay_ms(rt_get_int(count));
424423
return py_const_none;
@@ -436,19 +435,44 @@ py_obj_t pyb_sw() {
436435
return py_const_false;
437436
}
438437
}
439-
*/
440-
441-
#include "asmthumb.h"
442-
typedef void (*fun_t)();
443438

444439
#include "ff.h"
445440
FATFS fatfs0;
446441

442+
#include "nlr.h"
443+
void g(uint i) {
444+
printf("g:%d\n", i);
445+
if (i & 1) {
446+
nlr_jump((void*)(42 + i));
447+
}
448+
}
449+
void f() {
450+
nlr_buf_t nlr;
451+
int i;
452+
for (i = 0; i < 4; i++) {
453+
printf("f:loop:%d:%p\n", i, &nlr);
454+
if (nlr_push(&nlr) == 0) {
455+
// normal
456+
//printf("a:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
457+
g(i);
458+
printf("f:lp:%d:nrm\n", i);
459+
nlr_pop();
460+
} else {
461+
// nlr
462+
//printf("b:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
463+
printf("f:lp:%d:nlr:%d\n", i, (int)nlr.ret_val);
464+
}
465+
}
466+
}
467+
void nlr_test() {
468+
f(1);
469+
}
470+
447471
int main() {
448472
// should disable JTAG
449473

450-
//qstr_init();
451-
//rt_init();
474+
qstr_init();
475+
rt_init();
452476

453477
gpio_init();
454478
led_init();
@@ -503,9 +527,11 @@ int main() {
503527
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
504528
//delay_ms(1000);
505529

506-
#if 0
530+
nlr_test();
531+
532+
#if 1
507533
// Python!
508-
if (0) {
534+
if (1) {
509535
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
510536
const char *pysrc =
511537
// impl01.py
@@ -521,6 +547,7 @@ int main() {
521547
" x = x + 1\n";
522548
*/
523549
// impl02.py
550+
/*
524551
"#@micropython.native\n"
525552
"def f():\n"
526553
" x = 0\n"
@@ -533,6 +560,7 @@ int main() {
533560
" y = y + 1\n"
534561
" x = x + 1\n"
535562
"f()\n";
563+
*/
536564
/*
537565
"print('in python!')\n"
538566
"x = 0\n"
@@ -573,6 +601,23 @@ int main() {
573601
" x = x + 1\n"
574602
"flash(20)\n";
575603
*/
604+
// impl18.py
605+
/*
606+
"# basic exceptions\n"
607+
"x = 1\n"
608+
"try:\n"
609+
" x.a()\n"
610+
"except:\n"
611+
" print(x)\n";
612+
*/
613+
// impl19.py
614+
"# for loop\n"
615+
"def f():\n"
616+
" for x in range(400):\n"
617+
" for y in range(400):\n"
618+
" for z in range(400):\n"
619+
" pass\n"
620+
"f()\n";
576621

577622
py_lexer_t *lex = py_lexer_from_str_len("<>", pysrc, strlen(pysrc), false);
578623

@@ -605,17 +650,30 @@ int main() {
605650

606651
py_obj_t module_fun = rt_make_function_from_id(1);
607652

653+
// flash once
608654
led_state(PYB_LEDG1_PORT_NUM, 1);
609655
delay_ms(100);
610656
led_state(PYB_LEDG1_PORT_NUM, 0);
611-
py_obj_t ret = rt_call_function_0(module_fun);
657+
658+
nlr_buf_t nlr;
659+
if (nlr_push(&nlr) == 0) {
660+
py_obj_t ret = rt_call_function_0(module_fun);
661+
printf("done! got: ");
662+
py_obj_print(ret);
663+
printf("\n");
664+
nlr_pop();
665+
} else {
666+
// uncaught exception
667+
printf("exception: ");
668+
py_obj_print((py_obj_t)nlr.ret_val);
669+
printf("\n");
670+
}
671+
672+
// flash once
612673
led_state(PYB_LEDG1_PORT_NUM, 1);
613674
delay_ms(100);
614675
led_state(PYB_LEDG1_PORT_NUM, 0);
615676

616-
printf("done! got: ");
617-
py_obj_print(ret);
618-
printf("\n");
619677
delay_ms(1000);
620678
printf("nalloc=%u\n", m_get_total_bytes_allocated());
621679
delay_ms(1000);
@@ -690,7 +748,7 @@ int main() {
690748
}
691749

692750
// fatfs testing
693-
if (1) {
751+
if (0) {
694752
FRESULT res = f_mount(&fatfs0, "0:", 1);
695753
if (res == FR_OK) {
696754
printf("mount success\n");
@@ -730,7 +788,7 @@ int main() {
730788
DWORD nclst;
731789
FATFS *fatfs;
732790
f_getfree("0:", &nclst, &fatfs);
733-
printf("free=%d\n", nclst * fatfs->csize * 512);
791+
printf("free=%u\n", (uint)(nclst * fatfs->csize * 512));
734792

735793
}
736794

@@ -745,7 +803,7 @@ int main() {
745803
}
746804

747805
// USB testing
748-
if (1) {
806+
if (0) {
749807
void usb_init();
750808
usb_init();
751809
}

0 commit comments

Comments
 (0)