|
8 | 8 | //! debugger using these commands: |
9 | 9 | //! |
10 | 10 | //! ``` text |
| 11 | +//! (gdb) continue |
| 12 | +//! Program received signal SIGTRAP, Trace/breakpoint trap. |
| 13 | +//! __bkpt () at asm/bkpt.s:3 |
| 14 | +//! 3 bkpt |
| 15 | +//! |
| 16 | +//! (gdb) finish |
| 17 | +//! Run till exit from #0 __bkpt () at asm/bkpt.s:3 |
| 18 | +//! Note: automatically using hardware breakpoints for read-only addresses. |
| 19 | +//! crash::hf (_ef=0x20004fa0) at examples/crash.rs:102 |
| 20 | +//! 99 asm::bkpt(); |
| 21 | +//! |
11 | 22 | //! (gdb) # Exception frame = program state during the crash |
12 | | -//! (gdb) print/x *ef |
13 | | -//! $1 = cortex_m::exception::ExceptionFrame { |
14 | | -//! r0 = 0x2fffffff, |
15 | | -//! r1 = 0x2fffffff, |
16 | | -//! r2 = 0x0, |
17 | | -//! r3 = 0x0, |
18 | | -//! r12 = 0x0, |
19 | | -//! lr = 0x8000481, |
20 | | -//! pc = 0x8000460, |
21 | | -//! xpsr = 0x61000000, |
| 23 | +//! (gdb) print/x *_ef |
| 24 | +//! $1 = cortex_m_rt::ExceptionFrame { |
| 25 | +//! r0: 0x2fffffff, |
| 26 | +//! r1: 0x2fffffff, |
| 27 | +//! r2: 0x80006b0, |
| 28 | +//! r3: 0x80006b0, |
| 29 | +//! r12: 0x20000000, |
| 30 | +//! lr: 0x800040f, |
| 31 | +//! pc: 0x800066a, |
| 32 | +//! xpsr: 0x61000000 |
22 | 33 | //! } |
23 | 34 | //! |
24 | 35 | //! (gdb) # Where did we come from? |
25 | 36 | //! (gdb) backtrace |
26 | | -//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..) |
27 | | -//! #1 <signal handler called> |
28 | | -//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..) |
29 | | -//! #3 0x08000480 in crash::main () at examples/crash.rs:68 |
| 37 | +//! #0 crash::hf (_ef=0x20004fa0) at examples/crash.rs:102 |
| 38 | +//! #1 0x080004ac in UserHardFault (ef=0x20004fa0) at <exception macros>:9 |
| 39 | +//! #2 <signal handler called> |
| 40 | +//! #3 0x0800066a in core::ptr::read_volatile (src=0x2fffffff) at /checkout/src/libcore/ptr.rs:452 |
| 41 | +//! #4 0x0800040e in crash::main () at examples/crash.rs:85 |
| 42 | +//! #5 0x08000456 in main () at <main macros>:3 |
30 | 43 | //! |
31 | 44 | //! (gdb) # Nail down the location of the crash |
32 | | -//! (gdb) disassemble/m ef.pc |
33 | | -//! Dump of assembler code for function core::ptr::read_volatile<u32>: |
34 | | -//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T { |
35 | | -//! 0x08000454 <+0>: sub sp, #20 |
36 | | -//! 0x08000456 <+2>: mov r1, r0 |
37 | | -//! 0x08000458 <+4>: str r0, [sp, #8] |
38 | | -//! 0x0800045a <+6>: ldr r0, [sp, #8] |
39 | | -//! 0x0800045c <+8>: str r0, [sp, #12] |
| 45 | +//! (gdb) disassemble/m _ef.pc |
| 46 | +//! Dump of assembler code for function core::ptr::read_volatile: |
| 47 | +//! 451 pub unsafe fn read_volatile<T>(src: *const T) -> T {} |
| 48 | +//! 0x08000662 <+0>: sub sp, #16 |
| 49 | +//! 0x08000664 <+2>: mov r1, r0 |
| 50 | +//! 0x08000666 <+4>: str r0, [sp, #8] |
40 | 51 | //! |
41 | | -//! 409 intrinsics::volatile_load(src) |
42 | | -//! 0x0800045e <+10>: ldr r0, [sp, #12] |
43 | | -//! 0x08000460 <+12>: ldr r0, [r0, #0] |
44 | | -//! 0x08000462 <+14>: str r0, [sp, #16] |
45 | | -//! 0x08000464 <+16>: ldr r0, [sp, #16] |
46 | | -//! 0x08000466 <+18>: str r1, [sp, #4] |
47 | | -//! 0x08000468 <+20>: str r0, [sp, #0] |
48 | | -//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24> |
| 52 | +//! 452 intrinsics::volatile_load(src) |
| 53 | +//! 0x08000668 <+6>: ldr r0, [sp, #8] |
| 54 | +//! 0x0800066a <+8>: ldr r0, [r0, #0] |
| 55 | +//! 0x0800066c <+10>: str r0, [sp, #12] |
| 56 | +//! 0x0800066e <+12>: ldr r0, [sp, #12] |
| 57 | +//! 0x08000670 <+14>: str r1, [sp, #4] |
| 58 | +//! 0x08000672 <+16>: str r0, [sp, #0] |
| 59 | +//! 0x08000674 <+18>: b.n 0x8000676 <core::ptr::read_volatile+20> |
49 | 60 | //! |
50 | | -//! 410 } |
51 | | -//! 0x0800046c <+24>: ldr r0, [sp, #0] |
52 | | -//! 0x0800046e <+26>: add sp, #20 |
53 | | -//! 0x08000470 <+28>: bx lr |
| 61 | +//! 453 } |
| 62 | +//! 0x08000676 <+20>: ldr r0, [sp, #0] |
| 63 | +//! 0x08000678 <+22>: add sp, #16 |
| 64 | +//! 0x0800067a <+24>: bx lr |
54 | 65 | //! |
55 | 66 | //! End of assembler dump. |
56 | 67 | //! ``` |
57 | 68 | //! |
58 | 69 | //! --- |
59 | 70 |
|
60 | | -#![feature(used)] |
| 71 | +#![no_main] |
61 | 72 | #![no_std] |
62 | 73 |
|
63 | 74 | extern crate cortex_m; |
64 | | -extern crate cortex_m_rt; |
| 75 | +#[macro_use] |
| 76 | +extern crate cortex_m_rt as rt; |
65 | 77 | extern crate panic_abort; // panicking behavior |
66 | 78 |
|
67 | 79 | use core::ptr; |
68 | 80 |
|
69 | 81 | use cortex_m::asm; |
| 82 | +use rt::ExceptionFrame; |
| 83 | + |
| 84 | +main!(main); |
70 | 85 |
|
71 | | -fn main() { |
72 | | - // Read an invalid memory address |
| 86 | +#[inline(always)] |
| 87 | +fn main() -> ! { |
73 | 88 | unsafe { |
74 | 89 | ptr::read_volatile(0x2FFF_FFFF as *const u32); |
75 | 90 | } |
| 91 | + |
| 92 | + loop {} |
| 93 | +} |
| 94 | + |
| 95 | +exception!(DefaultHandler, dh); |
| 96 | + |
| 97 | +#[inline(always)] |
| 98 | +fn dh(_nr: u8) { |
| 99 | + asm::bkpt(); |
76 | 100 | } |
77 | 101 |
|
78 | | -// As we are not using interrupts, we just register a dummy catch all handler |
79 | | -#[link_section = ".vector_table.interrupts"] |
80 | | -#[used] |
81 | | -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; |
| 102 | +exception!(HardFault, hf); |
82 | 103 |
|
83 | | -extern "C" fn default_handler() { |
| 104 | +#[inline(always)] |
| 105 | +fn hf(_ef: &ExceptionFrame) -> ! { |
84 | 106 | asm::bkpt(); |
| 107 | + |
| 108 | + loop {} |
85 | 109 | } |
| 110 | + |
| 111 | +interrupts!(DefaultHandler); |
0 commit comments