-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Make raising SystemExit
do a soft reset on bare-metal targets
#15486
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
Make raising SystemExit
do a soft reset on bare-metal targets
#15486
Conversation
This is related to #12802 which makes a similar change, but I think it's worth putting this in a dedicated PR for visibility. |
Code size report:
|
fe997bd
to
1d95f35
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #15486 +/- ##
=======================================
Coverage 98.42% 98.42%
=======================================
Files 161 161
Lines 21252 21252
=======================================
Hits 20918 20918
Misses 334 334 ☔ View full report in Codecov by Sentry. |
Ah, for some reason I had in my head that Regardless, this looks good to me and I think it makes sense for It's certainly true that there could be other users out there expecting to use it as a silent drop to repl, but that seems fairly unlikley to me? |
Yes, it's possible some code is relying on this behaviour. But it would be an uncommon use, I'm guessing.
Exactly. And doing it that way (with an |
I like this change! since an embedded system is supposed to run indefinitely after being deployed, so doing a soft reset after a SystemExit seems more consistent and logical. |
+1 to this. It makes sense and prevents surprises related to DMA, PIO, etc allocation on rp2 at least. I don't believe we have any deployments or devices using SystemExit to mean "exit to repl" at the moment, but if we do it's just another thing for us to fix. |
The current situation with SystemExit and soft reset is the following: - `sys.exit()` follows CPython and just raises `SystemExit`. - On the unix port, raising `SystemExit` quits the application/MicroPython, whether at the REPL or in code (this follows CPython behaviour). - On bare-metal ports, raising `SystemExit` at the REPL does nothing, raising it in code will stop the code and drop into the REPL. - `machine.soft_reset()` raises `SystemExit` but with a special flag set, and bare-metal targets check this flag when it propagates to the top-level and do a soft reset when they receive it. The original idea here was that a bare-metal target can't "quit" like the unix port can, and so dropping to the REPL was considered the same as "quit". But this bare-metal behaviour is arguably inconsistent with unix, and "quit" should mean terminate everything, including REPL access. This commit changes the behaviour to the following, which is more consistent: - Raising `SystemExit` on a bare-metal port will do a soft reset (unless the exception is caught by the application). - `machine.soft_reset()` is now equivalent to `sys.exit()`. - unix port behaviour remains unchanged. Tested running the test suite on an stm32 board and everything still passes, in particular tests that skip by raising `SystemExit` still correctly skip. Signed-off-by: Damien George <[email protected]>
It does the same thing, raising `SystemExit`. Signed-off-by: Damien George <[email protected]>
1d95f35
to
5f3ecc2
Compare
Thanks for the reviews! |
Nice one, I'll rebase my PR onto master |
Unfortunately this change is not fully compatible with CPython behaviour. Running CPython with
But with this PR (which is merged), on bare-metal a If we consider the REPL on bare-metal to be the equivalent of I see two options:
Note that option (1) means there's no clean way for an application to abort and drop to the REPL. You would need to create a custom exception derived from |
@dpgeorge I don't quite follow: if this is optional behaviour on CPython (enabled by |
That's a good point, and maybe that is the right way to look at it. My thinking was that bare-metal has inspect mode that is switched on by default. Considering you can't specify command-line options on bare-metal, this seems reasonable? Bare-metal is kind of like CPython's |
Oh, I see the reasoning now. I guess, as you say, MicroPython on bare metal doesn't cleanly map to either "inspect mode" or regular CPython behaviour at the moment - but I can see the resemblance to inspect mode.
It's hacky but another option would be to programmatically For my 2c, having an automatically executed embedded application automatically drop to a REPL on "exit" seems more like a footgun than useful behaviour in most circumstances, but it's possible I'm not thinking through all the ways people might want to use this. |
Yes. Or just
Yes, I tend to agree with that. You could then argue that we shouldn't ever drop to the REPL (eg on an uncaught exception), but then things like |
Summary
The current situation with
SystemExit
and soft reset is the following:sys.exit()
follows CPython and just raisesSystemExit
SystemExit
quits the application / MicroPython, whether at the REPL or in code (this follows CPython behaviour)SystemExit
at the REPL does nothing, raising it in code will stop the code and drop into the REPLmachine.soft_reset()
raisesSystemExit
but with a special flag set, and bare-metal targets check this flag when it propagates to the top-level and do a soft reset when they receive itThe original idea here was that a bare-metal target can't "quit" like the unix port can, and so dropping to the REPL was considered the same as "quit". But this bare-metal behaviour is arguably inconsistent with unix.
This PR proposes to change the behaviour to the following, which is more consistent:
SystemExit
on a bare-metal port will do a soft reset (unless the exception is caught by the application)machine.soft_reset()
is now equivalent tosys.exit()
Testing
Tested running the test suite on PYBD-SF6 and everything still passes (in particular tests that skip by raising
SystemExit
still correctly skip).Trade-offs and Alternatives
This decreases code size, simplifies behaviour and makes unix and bare-metal behaviour match (and match CPython).
It is a breaking change though, if users are expecting
SystemExit
to just drop to the REPL. The alternative would be to not make this change.