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
//! Debugging a crash (exception)
//!
//! The `cortex-m-rt` crate provides functionality for this through a default
//! exception handler. When an exception is hit, the default handler will
//! trigger a breakpoint and in this debugging context the stacked registers
//! are accessible.
//!
//! In you run the example below, you'll be able to inspect the state of your
//! program under the debugger using these commands:
//!
//! ``` text
//! (gdb) # Exception frame = program state during the crash
//! (gdb) print/x *ef
//! $1 = cortex_m::exception::ExceptionFrame {
//!   r0 = 0x2fffffff,
//!   r1 = 0x2fffffff,
//!   r2 = 0x0,
//!   r3 = 0x0,
//!   r12 = 0x0,
//!   lr = 0x8000481,
//!   pc = 0x8000460,
//!   xpsr = 0x61000000,
//! }
//!
//! (gdb) # Where did we come from?
//! (gdb) backtrace
//! #0  cortex_m_rt::default_handler (ef=0x20004f54) at (..)
//! #1  <signal handler called>
//! #2  0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..)
//! #3  0x08000480 in crash::main () at examples/crash.rs:68
//!
//! (gdb) # Nail down the location of the crash
//! (gdb) disassemble/m ef.pc
//! Dump of assembler code for function core::ptr::read_volatile<u32>:
//! 408     pub unsafe fn read_volatile<T>(src: *const T) -> T {
//!    0x08000454 <+0>:     sub     sp, #20
//!    0x08000456 <+2>:     mov     r1, r0
//!    0x08000458 <+4>:     str     r0, [sp, #8]
//!    0x0800045a <+6>:     ldr     r0, [sp, #8]
//!    0x0800045c <+8>:     str     r0, [sp, #12]
//!
//! 409         intrinsics::volatile_load(src)
//!    0x0800045e <+10>:    ldr     r0, [sp, #12]
//!    0x08000460 <+12>:    ldr     r0, [r0, #0]
//!    0x08000462 <+14>:    str     r0, [sp, #16]
//!    0x08000464 <+16>:    ldr     r0, [sp, #16]
//!    0x08000466 <+18>:    str     r1, [sp, #4]
//!    0x08000468 <+20>:    str     r0, [sp, #0]
//!    0x0800046a <+22>:    b.n     0x800046c <core::ptr::read_volatile<u32>+24>
//!
//! 410     }
//!    0x0800046c <+24>:    ldr     r0, [sp, #0]
//!    0x0800046e <+26>:    add     sp, #20
//!    0x08000470 <+28>:    bx      lr
//!
//! End of assembler dump.
//! ```
//!
//! ---
//!
//! ```
//! 
//! #![feature(used)]
//! #![no_std]
//! 
//! extern crate cortex_m;
//! extern crate cortex_m_rt;
//! 
//! use core::ptr;
//! 
//! use cortex_m::asm;
//! 
//! fn main() {
//!     // Read an invalid memory address
//!     unsafe {
//!         ptr::read_volatile(0x2FFF_FFFF as *const u32);
//!     }
//! }
//! 
//! // As we are not using interrupts, we just register a dummy catch all handler
//! #[link_section = ".vector_table.interrupts"]
//! #[used]
//! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
//! 
//! extern "C" fn default_handler() {
//!     asm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.