NLR and Python exceptions work on the board.
This commit is contained in:
parent
c9f91976e1
commit
152568bcb6
10
py/nlr.h
10
py/nlr.h
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#ifndef __WORDSIZE
|
//#ifndef __WORDSIZE
|
||||||
#error __WORDSIZE needs to be defined
|
//#error __WORDSIZE needs to be defined
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
typedef struct _nlr_buf_t nlr_buf_t;
|
typedef struct _nlr_buf_t nlr_buf_t;
|
||||||
struct _nlr_buf_t {
|
struct _nlr_buf_t {
|
||||||
|
@ -17,7 +17,9 @@ struct _nlr_buf_t {
|
||||||
#elif __WORDSIZE == 64
|
#elif __WORDSIZE == 64
|
||||||
void *regs[8];
|
void *regs[8];
|
||||||
#else
|
#else
|
||||||
#error Unsupported __WORDSIZE
|
// hack for thumb
|
||||||
|
void *regs[10];
|
||||||
|
//#error Unsupported __WORDSIZE
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
@ thumb callee save: bx, bp, sp, r12, r14, r14, r15
|
||||||
|
|
||||||
|
.syntax unified
|
||||||
|
.cpu cortex-m4
|
||||||
|
.thumb
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
@ uint nlr_push(r0=nlr_buf_t *nlr)
|
||||||
|
.global nlr_push
|
||||||
|
.thumb
|
||||||
|
.thumb_func
|
||||||
|
.type nlr_push, %function
|
||||||
|
nlr_push:
|
||||||
|
str lr, [r0, #8] @ store lr into nlr_buf
|
||||||
|
str r4, [r0, #12] @ store r4 into nlr_buf
|
||||||
|
str r5, [r0, #16] @ store r5 into nlr_buf
|
||||||
|
str r6, [r0, #20] @ store r6 into nlr_buf
|
||||||
|
str r7, [r0, #24] @ store r7 into nlr_buf
|
||||||
|
str r8, [r0, #28] @ store r8 into nlr_buf
|
||||||
|
str r9, [r0, #32] @ store r9 into nlr_buf
|
||||||
|
str r10, [r0, #36] @ store r10 into nlr_buf
|
||||||
|
str r11, [r0, #40] @ store r11 into nlr_buf
|
||||||
|
str r13, [r0, #44] @ store r13=sp into nlr_buf
|
||||||
|
|
||||||
|
ldr r3, .L2 @ load addr of nlr_top
|
||||||
|
ldr r2, [r3] @ load nlr_top
|
||||||
|
str r2, [r0] @ store nlr_top into nlr_buf
|
||||||
|
str r0, [r3] @ store nlr_buf into nlr_top (to link list)
|
||||||
|
|
||||||
|
movs r0, #0 @ return 0, normal return
|
||||||
|
bx lr @ return
|
||||||
|
.align 2
|
||||||
|
.L2:
|
||||||
|
.word .LANCHOR0
|
||||||
|
.size nlr_push, .-nlr_push
|
||||||
|
|
||||||
|
@ void nlr_pop()
|
||||||
|
.global nlr_pop
|
||||||
|
.thumb
|
||||||
|
.thumb_func
|
||||||
|
.type nlr_pop, %function
|
||||||
|
nlr_pop:
|
||||||
|
ldr r3, .L5 @ load addr of nlr_top
|
||||||
|
ldr r2, [r3] @ load nlr_top
|
||||||
|
ldr r2, [r2] @ load prev nlr_buf
|
||||||
|
str r2, [r3] @ store prev nlr_buf to nlr_top (to unlink list)
|
||||||
|
bx lr @ return
|
||||||
|
.align 2
|
||||||
|
.L5:
|
||||||
|
.word .LANCHOR0
|
||||||
|
.size nlr_pop, .-nlr_pop
|
||||||
|
|
||||||
|
@ void nlr_jump(r0=uint val)
|
||||||
|
.global nlr_jump
|
||||||
|
.thumb
|
||||||
|
.thumb_func
|
||||||
|
.type nlr_jump, %function
|
||||||
|
nlr_jump:
|
||||||
|
ldr r3, .L2 @ load addr of nlr_top
|
||||||
|
ldr r2, [r3] @ load nlr_top
|
||||||
|
str r0, [r2, #4] @ store return value
|
||||||
|
ldr r0, [r2] @ load prev nlr_buf
|
||||||
|
str r0, [r3] @ store prev nol_buf into nlr_top (to unlink list)
|
||||||
|
|
||||||
|
ldr lr, [r2, #8] @ load lr from nlr_buf
|
||||||
|
ldr r4, [r2, #12] @ load r4 from nlr_buf
|
||||||
|
ldr r5, [r2, #16] @ load r5 from nlr_buf
|
||||||
|
ldr r6, [r2, #20] @ load r6 from nlr_buf
|
||||||
|
ldr r7, [r2, #24] @ load r7 from nlr_buf
|
||||||
|
ldr r8, [r2, #28] @ load r8 from nlr_buf
|
||||||
|
ldr r9, [r2, #32] @ load r9 from nlr_buf
|
||||||
|
ldr r10, [r2, #36] @ load r10 from nlr_buf
|
||||||
|
ldr r11, [r2, #40] @ load r11 from nlr_buf
|
||||||
|
ldr r13, [r2, #44] @ load r13=sp from nlr_buf
|
||||||
|
|
||||||
|
movs r0, #1 @ return 1, non-local return
|
||||||
|
bx lr @ return
|
||||||
|
.align 2
|
||||||
|
.L6:
|
||||||
|
.word .LANCHOR0
|
||||||
|
.size nlr_jump, .-nlr_jump
|
||||||
|
|
||||||
|
@ local variable nlr_top
|
||||||
|
.bss
|
||||||
|
.align 2
|
||||||
|
.set .LANCHOR0,. + 0
|
||||||
|
.type nlr_top, %object
|
||||||
|
.size nlr_top, 4
|
||||||
|
nlr_top:
|
||||||
|
.space 4
|
13
stm/Makefile
13
stm/Makefile
|
@ -8,7 +8,6 @@ CC = arm-none-eabi-gcc
|
||||||
LD = arm-none-eabi-ld
|
LD = arm-none-eabi-ld
|
||||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfloat-abi=hard -DSTM32F40XX -DHSE_VALUE=8000000
|
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfloat-abi=hard -DSTM32F40XX -DHSE_VALUE=8000000
|
||||||
CFLAGS = -I. -I$(PYSRC) -I$(FATFSSRC) -I$(STMSRC) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4)
|
CFLAGS = -I. -I$(PYSRC) -I$(FATFSSRC) -I$(STMSRC) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4)
|
||||||
CFLAGS_PY = -DEMIT_ENABLE_THUMB
|
|
||||||
LDFLAGS = --nostdlib -T stm32f405.ld
|
LDFLAGS = --nostdlib -T stm32f405.ld
|
||||||
|
|
||||||
SRC_C = \
|
SRC_C = \
|
||||||
|
@ -27,7 +26,8 @@ SRC_S = \
|
||||||
startup_stm32f40xx.s \
|
startup_stm32f40xx.s \
|
||||||
|
|
||||||
PY_O = \
|
PY_O = \
|
||||||
# malloc.o \
|
nlrthumb.o \
|
||||||
|
malloc.o \
|
||||||
qstr.o \
|
qstr.o \
|
||||||
misc.o \
|
misc.o \
|
||||||
lexer.o \
|
lexer.o \
|
||||||
|
@ -109,15 +109,18 @@ $(BUILD)/%.o: $(FATFSSRC)/%.c
|
||||||
$(BUILD)/%.o: $(STMSRC)/%.c
|
$(BUILD)/%.o: $(STMSRC)/%.c
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD)/%.o: $(PYSRC)/%.s
|
||||||
|
$(AS) -c -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h
|
$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_PY) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
|
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_PY) -DN_THUMB -c -o $@ $<
|
$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
|
||||||
|
|
||||||
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
|
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
|
||||||
$(BUILD)/vm.o: $(PYSRC)/vm.c
|
$(BUILD)/vm.o: $(PYSRC)/vm.c
|
||||||
$(CC) $(CFLAGS) $(CFLAGS_PY) -O3 -c -o $@ $<
|
$(CC) $(CFLAGS) -O3 -c -o $@ $<
|
||||||
|
|
||||||
$(BUILD)/parse.o: $(PYSRC)/grammar.h
|
$(BUILD)/parse.o: $(PYSRC)/grammar.h
|
||||||
$(BUILD)/compile.o: $(PYSRC)/grammar.h
|
$(BUILD)/compile.o: $(PYSRC)/grammar.h
|
||||||
|
|
96
stm/main.c
96
stm/main.c
|
@ -418,7 +418,6 @@ void __fatal_error(const char *msg) {
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
/*
|
|
||||||
py_obj_t pyb_delay(py_obj_t count) {
|
py_obj_t pyb_delay(py_obj_t count) {
|
||||||
delay_ms(rt_get_int(count));
|
delay_ms(rt_get_int(count));
|
||||||
return py_const_none;
|
return py_const_none;
|
||||||
|
@ -436,19 +435,44 @@ py_obj_t pyb_sw() {
|
||||||
return py_const_false;
|
return py_const_false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#include "asmthumb.h"
|
|
||||||
typedef void (*fun_t)();
|
|
||||||
|
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
FATFS fatfs0;
|
FATFS fatfs0;
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
void g(uint i) {
|
||||||
|
printf("g:%d\n", i);
|
||||||
|
if (i & 1) {
|
||||||
|
nlr_jump((void*)(42 + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void f() {
|
||||||
|
nlr_buf_t nlr;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
printf("f:loop:%d:%p\n", i, &nlr);
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
// normal
|
||||||
|
//printf("a:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
|
||||||
|
g(i);
|
||||||
|
printf("f:lp:%d:nrm\n", i);
|
||||||
|
nlr_pop();
|
||||||
|
} else {
|
||||||
|
// nlr
|
||||||
|
//printf("b:%p:%p %p %p %u\n", &nlr, nlr.ip, nlr.sp, nlr.prev, nlr.ret_val);
|
||||||
|
printf("f:lp:%d:nlr:%d\n", i, (int)nlr.ret_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void nlr_test() {
|
||||||
|
f(1);
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// should disable JTAG
|
// should disable JTAG
|
||||||
|
|
||||||
//qstr_init();
|
qstr_init();
|
||||||
//rt_init();
|
rt_init();
|
||||||
|
|
||||||
gpio_init();
|
gpio_init();
|
||||||
led_init();
|
led_init();
|
||||||
|
@ -503,9 +527,11 @@ int main() {
|
||||||
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
||||||
//delay_ms(1000);
|
//delay_ms(1000);
|
||||||
|
|
||||||
#if 0
|
nlr_test();
|
||||||
|
|
||||||
|
#if 1
|
||||||
// Python!
|
// Python!
|
||||||
if (0) {
|
if (1) {
|
||||||
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
|
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
|
||||||
const char *pysrc =
|
const char *pysrc =
|
||||||
// impl01.py
|
// impl01.py
|
||||||
|
@ -521,6 +547,7 @@ int main() {
|
||||||
" x = x + 1\n";
|
" x = x + 1\n";
|
||||||
*/
|
*/
|
||||||
// impl02.py
|
// impl02.py
|
||||||
|
/*
|
||||||
"#@micropython.native\n"
|
"#@micropython.native\n"
|
||||||
"def f():\n"
|
"def f():\n"
|
||||||
" x = 0\n"
|
" x = 0\n"
|
||||||
|
@ -533,6 +560,7 @@ int main() {
|
||||||
" y = y + 1\n"
|
" y = y + 1\n"
|
||||||
" x = x + 1\n"
|
" x = x + 1\n"
|
||||||
"f()\n";
|
"f()\n";
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
"print('in python!')\n"
|
"print('in python!')\n"
|
||||||
"x = 0\n"
|
"x = 0\n"
|
||||||
|
@ -573,6 +601,23 @@ int main() {
|
||||||
" x = x + 1\n"
|
" x = x + 1\n"
|
||||||
"flash(20)\n";
|
"flash(20)\n";
|
||||||
*/
|
*/
|
||||||
|
// impl18.py
|
||||||
|
/*
|
||||||
|
"# basic exceptions\n"
|
||||||
|
"x = 1\n"
|
||||||
|
"try:\n"
|
||||||
|
" x.a()\n"
|
||||||
|
"except:\n"
|
||||||
|
" print(x)\n";
|
||||||
|
*/
|
||||||
|
// impl19.py
|
||||||
|
"# for loop\n"
|
||||||
|
"def f():\n"
|
||||||
|
" for x in range(400):\n"
|
||||||
|
" for y in range(400):\n"
|
||||||
|
" for z in range(400):\n"
|
||||||
|
" pass\n"
|
||||||
|
"f()\n";
|
||||||
|
|
||||||
py_lexer_t *lex = py_lexer_from_str_len("<>", pysrc, strlen(pysrc), false);
|
py_lexer_t *lex = py_lexer_from_str_len("<>", pysrc, strlen(pysrc), false);
|
||||||
|
|
||||||
|
@ -605,17 +650,30 @@ int main() {
|
||||||
|
|
||||||
py_obj_t module_fun = rt_make_function_from_id(1);
|
py_obj_t module_fun = rt_make_function_from_id(1);
|
||||||
|
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
// flash once
|
||||||
delay_ms(100);
|
led_state(PYB_LEDG1_PORT_NUM, 1);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
delay_ms(100);
|
||||||
py_obj_t ret = rt_call_function_0(module_fun);
|
led_state(PYB_LEDG1_PORT_NUM, 0);
|
||||||
|
|
||||||
|
nlr_buf_t nlr;
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
py_obj_t ret = rt_call_function_0(module_fun);
|
||||||
|
printf("done! got: ");
|
||||||
|
py_obj_print(ret);
|
||||||
|
printf("\n");
|
||||||
|
nlr_pop();
|
||||||
|
} else {
|
||||||
|
// uncaught exception
|
||||||
|
printf("exception: ");
|
||||||
|
py_obj_print((py_obj_t)nlr.ret_val);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// flash once
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 1);
|
led_state(PYB_LEDG1_PORT_NUM, 1);
|
||||||
delay_ms(100);
|
delay_ms(100);
|
||||||
led_state(PYB_LEDG1_PORT_NUM, 0);
|
led_state(PYB_LEDG1_PORT_NUM, 0);
|
||||||
|
|
||||||
printf("done! got: ");
|
|
||||||
py_obj_print(ret);
|
|
||||||
printf("\n");
|
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
printf("nalloc=%u\n", m_get_total_bytes_allocated());
|
printf("nalloc=%u\n", m_get_total_bytes_allocated());
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
|
@ -690,7 +748,7 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fatfs testing
|
// fatfs testing
|
||||||
if (1) {
|
if (0) {
|
||||||
FRESULT res = f_mount(&fatfs0, "0:", 1);
|
FRESULT res = f_mount(&fatfs0, "0:", 1);
|
||||||
if (res == FR_OK) {
|
if (res == FR_OK) {
|
||||||
printf("mount success\n");
|
printf("mount success\n");
|
||||||
|
@ -730,7 +788,7 @@ int main() {
|
||||||
DWORD nclst;
|
DWORD nclst;
|
||||||
FATFS *fatfs;
|
FATFS *fatfs;
|
||||||
f_getfree("0:", &nclst, &fatfs);
|
f_getfree("0:", &nclst, &fatfs);
|
||||||
printf("free=%d\n", nclst * fatfs->csize * 512);
|
printf("free=%u\n", (uint)(nclst * fatfs->csize * 512));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +803,7 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// USB testing
|
// USB testing
|
||||||
if (1) {
|
if (0) {
|
||||||
void usb_init();
|
void usb_init();
|
||||||
usb_init();
|
usb_init();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue