flagxor / ueforth

Apache License 2.0
94 stars 26 forks source link

Initial stack for interrupt handlers #13

Open arcli opened 3 years ago

arcli commented 3 years ago

First of all, thank you for ESP32Forth. It's perfect for the project I'm doing. As my first forth, I'm enjoying learning about the internals of the implementation as well as the language.

I love the ease of adding existing Arduino libraries. As part of adding ESP-NOW support I need a way to pass arguments received in an interrupt routine into forth. I'm using your existing pinchange and HandleInterrupt code as a template. However for me the one-item stack that is set up in HandleInterrupt in lines 496 and 498 is not making it into forth.

My simple test:

interrupts
: chg  depth . cr ;
' chg 13 pinchange
--> -38717

I think the DROP on line 31 of forth_run may be interfering with things but I'm not very familiar with the memory layout. If this is indeed a bug I'm happy to work on a fix but I could use some guidance.

Thanks in advance.

https://github.com/flagxor/eforth/blob/168f68963164f2df65c483da0cc31d5717419f62/ueforth/esp32/bindings.fs#L150-L151

https://github.com/flagxor/eforth/blob/168f68963164f2df65c483da0cc31d5717419f62/ueforth/esp32/template.ino#L489-L501

https://github.com/flagxor/eforth/blob/168f68963164f2df65c483da0cc31d5717419f62/ueforth/common/interp.h#L21-L40

arcli commented 2 years ago

After more research into adjusting the stack ahead of calling the xt, a simpler (and working) option is to push the value on the stack via code, as below. I'd welcome any criticisms, corrections, and suggestions. For now this solves my immediate issue and doesn't seem too hacky. Thanks!

diff --git a/ueforth/esp32/template.ino b/ueforth/esp32/template.ino
index 4b77596..122122a 100644
--- a/ueforth/esp32/template.ino
+++ b/ueforth/esp32/template.ino
@@ -488,12 +488,13 @@ struct handle_interrupt_args {

 static void IRAM_ATTR HandleInterrupt(void *arg) {
   struct handle_interrupt_args *args = (struct handle_interrupt_args *) arg;
-  cell_t code[2];
-  code[0] = args->xt;
-  code[1] = g_sys.YIELD_XT;
+  cell_t code[4];
+  code[0] = g_sys.DOLIT_XT;
+  code[1] = args->arg;
+  code[2] = args->xt;
+  code[3] = g_sys.YIELD_XT;
   cell_t stack[INTERRUPT_STACK_CELLS];
   cell_t rstack[INTERRUPT_STACK_CELLS];
-  stack[0] = args->arg;
   cell_t *rp = rstack;
   *++rp = (cell_t) (stack + 1);
   *++rp = (cell_t) code;