cortex-m
cortex-m copied to clipboard
Using semihosting with no debugger attached
Currently it's not possible to run code that contains semihosting calls without having a debugger attached, since semihosting relies on the debugger catching bkpt 0xab and without a debugger, this will trigger an exception and halt the mcu in most cases. I read that some semihosting C runtime provides an exception handler that is able to ignore this exception so that the mcu keeps running even without a debugger attached.
Even though semihosting is not meant to be used without a debugger, it might be useful to be able to run without one. It should at least be mentioned in the docs to make developers aware of it. Otherwise they might wonder why their code stops working when they plug out the debugger.
Unfortunately, this crate can't patch the vector table to catch and ignore the exception automatically, but we could try to find a way to make it trivial for the user to install such a handler (like providing the handler and the user just has to add it to the vector table)
What I do in the cortex-m-rt crate for panic! messages is: use cfg directives in the panic_fmt implementation to allow switching between: panic! prints no message, panic! prints its message to the host using semihosting, and panic! prints sends its message through ITM port 0 through Cago features.
This works fine because applications always directly depend on the cortex-m-rt crate so they can easily switch between these modes by changing the features of the cortex-m-rt.
Something like this could be done here but I'm not sure how helpful that would be. We could provide a Cargo feature to cfg away the semihosting call in the iprint macros. But this method is only effective when the application directly depends on the cortex-m-semihosting because flipping a Cargo feature of the dependency of a dependency requires cooperation of the dependencies in between. Also note that because of how Cargo features work if any dependency depends on cortex-m-semihosting with the "do a semihosting call in iprint!" feature enabled then Cargo will enable that features on all instances of the cortex-m-semihosting crate that appear in the dependency graph.
I think is most effective if the application, the top crate, creates its own print macro that looks like this:
#[cfg(feature = "use_semihosting")
macro_rules! my_print {
() => { .. };
}
#[cfg(not(feature = "use_semihosting"))
macro_rules! my_print {
() => {};
}
then the application can control what my_print! exactly does.
I was just surprised by this and found this issue. Things have changed with the new panic crates. What's the recommendation now? As a more casual user than I suspect either of you are, my simplistic thought is that I'd like to use a feature to enable/disable semihosting, as that feels a bit more convenient. I realize that things are in flux at the moment, but I wonder what the longer term vision is for this?
related, but not strictly tied to this particular issue: it feels like there should be a debug/logging crate that holds the macros and respects the feature flags to select between nop logging, semihosting and itm. That would help while debugging hal implementations also; this is one of the things that feels a bit awkward to me today, but I confess to being more of a printf debugging person than a stepping through a debugger person.
Such a debug crate could/should grow serial/usb-cdc logging in the future too.
Just wanted to add a vote for a use-case here: using panic-semihosting to mirror the existing Rust test ergonomics.
panic-semihosting lets me use the standard assert_eq! and assert! macro calls in my existing tests and log them on the host. If I'm processing tests with some log processing I can see how many tests failed and know the QEMU process exits at the end of all tests if I'm doing simulated testing. With a bkpt it's more difficult unless I drive it with a debugger or Python.
There may be a better solution, maybe panic-itm. I'm still familiarizing myself with embedded test best practices. It does kind of go against the semantics of "panic" too.
Anyways, a solution might be to add another feature flag that provides a third case in panic-semihosting/src/lib.rs: "panic-semihosting-continue" or something?