panic_itm/
lib.rs

1//! Log panic messages using the ITM (Instrumentation Trace Macrocell)
2//!
3//! This crate contains an implementation of `panic_fmt` that logs panic messages to the ITM
4//! stimulus port 0. Before printing the message the panic handler disables (masks) all the device
5//! specific interrupts. After printing the message the panic handler goes into an infinite loop.
6//!
7//! # Usage
8//!
9//! ``` ignore
10//! #![no_std]
11//!
12//! extern crate panic_itm;
13//!
14//! fn main() {
15//!     panic!("FOO")
16//! }
17//! ```
18//!
19//! ``` text
20//! (gdb) monitor tpiu config external uart off 8000000 2000000
21//! (gdb) monitor itm port 0 on
22//! (gdb) continue
23//! (..)
24//! ```
25//!
26//! ``` text
27//! $ itmdump -f /dev/ttyUSB0
28//! panicked at 'FOO', src/main.rs:6:5
29//! ```
30
31#![cfg(all(target_arch = "arm", target_os = "none"))]
32#![deny(missing_docs)]
33#![deny(warnings)]
34#![no_std]
35
36extern crate cortex_m;
37
38use core::panic::PanicInfo;
39use core::sync::atomic::{self, Ordering};
40
41use cortex_m::interrupt;
42use cortex_m::iprintln;
43use cortex_m::peripheral::ITM;
44
45#[panic_handler]
46fn panic(info: &PanicInfo) -> ! {
47    interrupt::disable();
48
49    let itm = unsafe { &mut *ITM::ptr() };
50    let stim = &mut itm.stim[0];
51
52    iprintln!(stim, "{}", info);
53
54    loop {
55        // add some side effect to prevent this from turning into a UDF instruction
56        // see rust-lang/rust#28728 for details
57        atomic::compiler_fence(Ordering::SeqCst);
58    }
59}