Skip to content
Snippets Groups Projects
Commit dba88fca authored by Per Lindgren's avatar Per Lindgren
Browse files

polish

parent 6fbf672a
No related branches found
No related tags found
No related merge requests found
//! Debugging a crash (exception)
// #![deny(unsafe_code)] // this example is using unsafe
#![deny(warnings)]
#![no_main]
#![no_std]
extern crate panic_halt;
//use panic_halt as _;
use panic_semihosting as _;
use core::ptr;
use cortex_m_rt::{entry, exception};
......@@ -24,82 +28,5 @@ fn main() -> ! {
#[exception]
#[inline(never)]
fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
// to inline never and read_volatile required to
// avoid `ef` being optimized out in release mode
unsafe {
ptr::read_volatile(ef);
}
loop {
continue;
}
panic!("Exception frame {:?}", ef);
}
//
// Most crash conditions trigger a hard fault exception, whose handler is defined via
// ``` rust
// #[exception]
// fn HardFault(ef: &cortex_m_rt::ExceptionFrame) -> ! {
// ...
// ```
//
// `cortex-m-rt` generates a trampoline, that calls into your user defined `
// HardFault` handler. We look at the generated trampoline:
//
// ``` rust
// #[doc(hidden)]
// #[export_name = "HardFault"]
// #[link_section = ".HardFault.user"]
// pub unsafe extern "C" fn __cortex_m_rt_HardFault_trampoline(frame: &::cortex_m_rt::ExceptionFrame) {
// __cortex_m_rt_HardFault(frame)
// }
// ```
//
// The `HardFault` handler has access to the exception `frame`, a
// snapshot of the CPU registers at the moment of the exception.
//
// To better see what is happening we make a `--release` build
// (It reduces the amount of redundant code.)
//
// ``` text
// $ cargo run --example crash --release
// ...
// Breakpoint 1, main () at examples/crash.rs:69
// (gdb) continue
// Breakpoint 3, HardFault (frame=0x20007fe0) at examples/crash.rs:82
// 82 #[exception]
// (gdb) p/x *frame
// $1 = cortex_m_rt::ExceptionFrame {r0: 0x2fffffff, r1: 0xf00000, r2: 0x0, r3: 0x0, r12: 0x0, lr: 0x8000405, pc: 0x800040a, xpsr: 0x61000000}
// (gdb) disassemble frame.pc
// Dump of assembler code for function crash::__cortex_m_rt_main:
// 0x08000406 <+0>: mvn.w r0, #3489660928 ; 0xd0000000
// 0x0800040a <+4>: ldr r0, [r0, #0]
// 0x0800040c <+6>: b.n 0x800040c <crash::__cortex_m_rt_main+6>
// End of assembler dump.
// ```
//
// The program counter (frame.pc) contains the address of the instruction that caused the exception. In GDB one can
// disassemble the program around this address to observe the instruction that caused the
// exception. In our case its the `ldr r0, [r0, #0]` caused the exception. This instruction tried to load (read) a 32-bit word
// from the address stored in the register `r0`. Looking again at the contents of `ExceptionFrame`
// we find that `r0` contained the address `0x2FFF_FFFF` when this instruction was executed.
//
// Looking at the assembly `mvn.w r0, #3489660928 ; 0xd0000000`.
// This is a *move* and *not*, so the resulting value here is actually
// 0x2fffffff. Why did it not do it straight up then as 0x2FFF_FFFF?
//
// Well a 32 bit constant cannot be stored in a 32 bit instruction.
// So under the hood it stores 0xd0, bit shifts it and bit wise inversion.
// This is the level of optimization Rust + LLVM is capable of.
//
// We can further backtrace the calls leading up to the fault.
// ``` text
// ((gdb) bt
// #0 HardFault (frame=0x20007fe0) at examples/crash.rs:79
// #1 <signal handler called>
// #2 core::ptr::read_volatile (src=0x2fffffff)
// at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ptr/mod.rs:948
// #3 crash::__cortex_m_rt_main () at examples/crash.rs:71
// #4 0x08000404 in main () at examples/crash.rs:66
// ```
// Here we see that on frame #2 we are doing the read causing havoc.
......@@ -5,7 +5,7 @@
#![no_std]
#[allow(unused_extern_crates)]
extern crate panic_halt;
use panic_halt as _;
use cortex_m::{iprint, peripheral::syst::SystClkSource};
use cortex_m_rt::entry;
......
......@@ -7,10 +7,11 @@
//! ---
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
extern crate panic_halt;
use panic_halt as _;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::Peripherals;
......
......@@ -4,13 +4,12 @@
//!
//! [1]: https://rust-embedded.github.io/cortex-m-rt/0.6.1/cortex_m_rt_macros/fn.exception.html
//!
//! Notice, steal will panic! in debug mode, due to a `debug_assert` (ignored in release).
//! ---
#![no_main]
#![no_std]
extern crate panic_halt;
use panic_halt as _;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::{iprint, iprintln, Peripherals};
......
......@@ -8,7 +8,7 @@
#![no_main]
#![no_std]
extern crate panic_halt;
use panic_halt as _;
use cortex_m::peripheral::{syst::SystClkSource, ITM};
use cortex_m::{iprint, iprintln, Peripherals};
......
//! Prints "Hello, world!" on the host console using semihosting
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
extern crate panic_halt;
use panic_halt as _;
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
......
......@@ -7,11 +7,12 @@
//! [`itmdump`]: https://docs.rs/itm/0.3.1/itm/
//!
//! ---
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
extern crate panic_halt;
use panic_halt as _;
use cortex_m::{iprintln, Peripherals};
use cortex_m_rt::entry;
......
......@@ -4,21 +4,21 @@
//!
//! [0]: https://crates.io/keywords/panic-impl
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
// Pick one of these panic handlers:
// `panic!` halts execution; the panic message is ignored
extern crate panic_halt;
use panic_halt as _;
// Reports panic messages to the host stderr using semihosting
// NOTE to use this you need to uncomment the `panic-semihosting` dependency in Cargo.toml
// extern crate panic_semihosting;
//use panic_semihosting as _;
// Logs panic messages using the ITM (Instrumentation Trace Macrocell)
// NOTE to use this you need to uncomment the `panic-itm` dependency in Cargo.toml
//extern crate panic_itm;
//use panic_itm as _;
use cortex_m_rt::entry;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment