Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupting loops #9

Open
leahneukirchen opened this issue Aug 15, 2022 · 1 comment
Open

Interrupting loops #9

leahneukirchen opened this issue Aug 15, 2022 · 1 comment

Comments

@leahneukirchen
Copy link

I didn't see any way to interrupt evaluation from the console, would it be possible to detect a BREAK on the serial line and throw and exception or something? It would simplify interactive usage, for now I had to reset on every infinite loop.

@tabemann
Copy link
Owner

tabemann commented Aug 16, 2022

I have thought of implementing this very feature that you suggest, but from some thought I have come to the conclusion that it has too much complexity and is hard to do safely if the goal is to return control to the REPL (what happens if you break during an operation on a lock or a channel?), especially since it would have to be done within an interrupt handler with any potential number of nested interrupts.

An alternative might be to trap a character in an interrupt handler and use it to signal a reboot. However, this would be the same as the manual reset you refer to, except it would be via serial, and it would not work if the MCU has crashed anyways. However, if you are using swdcom, ctrl-C for rebooting is not only baked into it but works even if the MCU has crashed since it uses ST-Link to do the rebooting; swdcom does not support the Raspberry Pi Pico though.

Of course, some terminals used with embedded Forth, such as e4thcom or my own zeptocom.js, do not allow the user to send arbitrary characters such as ctrl-C to the target. Also, if you dedicated a particular character to break it would deny use of that character by applications running within zeptoforth.

If you are running code that may run infinitely, I would suggest running it in a separate task from the main REPL task. Take the following:

task import
: test ( -- ) 0 [: begin put-your-code-here again ;] 320 128 512 spawn run ;

test when run will run put-your-code-here in an infinite loop, while still retaining a usable REPL. If you want to stop the task, one would reboot the MCU with reboot. If you want to be able to arbitrarily start and stop the task, you can do something like:

task import
variable my-task
: test ( -- ) 0 [: begin put-your-code-here again ;] 320 128 512 spawn my-task ! ;

Here you can then execute my-task @ run to start the task and my-task @ stop to stop the task, any number of times.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants