aboutsummaryrefslogtreecommitdiff
path: root/panic-semihosting/src/lib.rs
diff options
context:
space:
mode:
authorGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-08-31 23:16:21 +0200
committerGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-10-13 21:30:44 +0200
commit10b29d3a4fc43503c25fb2c7ffbeaad44c2fb103 (patch)
treeceb6fc008cfbcc430a4254464d0e3341c34796e1 /panic-semihosting/src/lib.rs
parentf77d64a2d1505335e4a170d03a40993bb066fd02 (diff)
downloadcortex-m-10b29d3a4fc43503c25fb2c7ffbeaad44c2fb103.tar.gz
cortex-m-10b29d3a4fc43503c25fb2c7ffbeaad44c2fb103.tar.zst
cortex-m-10b29d3a4fc43503c25fb2c7ffbeaad44c2fb103.zip
Import semihosting crates as-is
Diffstat (limited to 'panic-semihosting/src/lib.rs')
-rw-r--r--panic-semihosting/src/lib.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/panic-semihosting/src/lib.rs b/panic-semihosting/src/lib.rs
new file mode 100644
index 0000000..71d2774
--- /dev/null
+++ b/panic-semihosting/src/lib.rs
@@ -0,0 +1,95 @@
+//! Report panic messages to the host stderr using semihosting
+//!
+//! This crate contains an implementation of `panic_fmt` that logs panic messages to the host stderr
+//! using [`cortex-m-semihosting`]. Before logging the message the panic handler disables (masks)
+//! the device specific interrupts. After logging the message the panic handler trigger a breakpoint
+//! and then goes into an infinite loop.
+//!
+//! Currently, this crate only supports the ARM Cortex-M architecture.
+//!
+//! [`cortex-m-semihosting`]: https://crates.io/crates/cortex-m-semihosting
+//!
+//! # Usage
+//!
+//! ``` ignore
+//! #![no_std]
+//!
+//! extern crate panic_semihosting;
+//!
+//! fn main() {
+//! panic!("FOO")
+//! }
+//! ```
+//!
+//! ``` text
+//! (gdb) monitor arm semihosting enable
+//! (gdb) continue
+//! Program received signal SIGTRAP, Trace/breakpoint trap.
+//! rust_begin_unwind (args=..., file=..., line=8, col=5)
+//! at $CRATE/src/lib.rs:69
+//! 69 asm::bkpt();
+//! ```
+//!
+//! ``` text
+//! $ openocd -f (..)
+//! (..)
+//! panicked at 'FOO', src/main.rs:6:5
+//! ```
+//!
+//! # Optional features
+//!
+//! ## `exit`
+//!
+//! When this feature is enabled the panic handler performs an exit semihosting call after logging
+//! the panic message. This is useful when emulating the program on QEMU as it causes the QEMU
+//! process to exit with a non-zero exit code; thus it can be used to implement Cortex-M tests that
+//! run on the host.
+//!
+//! We discourage using this feature when the program will run on hardware as the exit call can
+//! leave the hardware debugger in an inconsistent state.
+//!
+//! ## `inline-asm`
+//!
+//! When this feature is enabled semihosting is implemented using inline assembly (`asm!`) and
+//! compiling this crate requires nightly.
+//!
+//! When this feature is disabled semihosting is implemented using FFI calls into an external
+//! assembly file and compiling this crate works on stable and beta.
+
+#![deny(missing_docs)]
+#![deny(warnings)]
+#![no_std]
+
+extern crate cortex_m;
+extern crate cortex_m_semihosting as sh;
+
+use core::fmt::Write;
+use core::panic::PanicInfo;
+
+#[cfg(not(feature = "exit"))]
+use cortex_m::asm;
+use cortex_m::interrupt;
+#[cfg(feature = "exit")]
+use sh::debug::{self, EXIT_FAILURE};
+use sh::hio;
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+ interrupt::disable();
+
+ if let Ok(mut hstdout) = hio::hstdout() {
+ writeln!(hstdout, "{}", info).ok();
+ }
+
+ match () {
+ // Exit the QEMU process
+ #[cfg(feature = "exit")]
+ () => debug::exit(EXIT_FAILURE),
+ // OK to fire a breakpoint here because we know the microcontroller is connected to a
+ // debugger
+ #[cfg(not(feature = "exit"))]
+ () => asm::bkpt(),
+ }
+
+ loop {}
+}