1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 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 {} }