drop linker-flavor, port more examples
This commit is contained in:
@@ -1,39 +1,27 @@
|
|||||||
[target.thumbv6m-none-eabi]
|
[target.thumbv6m-none-eabi]
|
||||||
runner = 'arm-none-eabi-gdb'
|
runner = 'arm-none-eabi-gdb'
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Wl,-Tlink.x",
|
||||||
"-C", "linker=lld",
|
"-C", "link-arg=-nostartfiles",
|
||||||
"-Z", "linker-flavor=ld.lld",
|
|
||||||
# "-C", "linker=arm-none-eabi-ld",
|
|
||||||
# "-Z", "linker-flavor=ld",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.thumbv7m-none-eabi]
|
[target.thumbv7m-none-eabi]
|
||||||
runner = 'arm-none-eabi-gdb'
|
runner = 'arm-none-eabi-gdb'
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Wl,-Tlink.x",
|
||||||
"-C", "linker=lld",
|
"-C", "link-arg=-nostartfiles",
|
||||||
"-Z", "linker-flavor=ld.lld",
|
|
||||||
# "-C", "linker=arm-none-eabi-ld",
|
|
||||||
# "-Z", "linker-flavor=ld",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.thumbv7em-none-eabi]
|
[target.thumbv7em-none-eabi]
|
||||||
runner = 'arm-none-eabi-gdb'
|
runner = 'arm-none-eabi-gdb'
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Wl,-Tlink.x",
|
||||||
"-C", "linker=lld",
|
"-C", "link-arg=-nostartfiles",
|
||||||
"-Z", "linker-flavor=ld.lld",
|
|
||||||
# "-C", "linker=arm-none-eabi-ld",
|
|
||||||
# "-Z", "linker-flavor=ld",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.thumbv7em-none-eabihf]
|
[target.thumbv7em-none-eabihf]
|
||||||
runner = 'arm-none-eabi-gdb'
|
runner = 'arm-none-eabi-gdb'
|
||||||
rustflags = [
|
rustflags = [
|
||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Wl,-Tlink.x",
|
||||||
"-C", "linker=lld",
|
"-C", "link-arg=-nostartfiles",
|
||||||
"-Z", "linker-flavor=ld.lld",
|
|
||||||
# "-C", "linker=arm-none-eabi-ld",
|
|
||||||
# "-Z", "linker-flavor=ld",
|
|
||||||
]
|
]
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
.#*
|
||||||
.gdb_history
|
.gdb_history
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
target/
|
target/
|
||||||
|
|||||||
13
Cargo.toml
13
Cargo.toml
@@ -9,15 +9,20 @@ repository = "https://github.com/japaric/cortex-m-quickstart"
|
|||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# cortex-m = "0.4.0"
|
# cortex-m-rt = "0.5.0"
|
||||||
# cortex-m-rt = "0.4.0"
|
|
||||||
cortex-m-rt = { git = "https://github.com/japaric/cortex-m-rt", branch = "stable" }
|
cortex-m-rt = { git = "https://github.com/japaric/cortex-m-rt", branch = "stable" }
|
||||||
# panic-loop = { path = "../panic-loop" }
|
|
||||||
panic-abort = "0.1.1"
|
panic-abort = "0.1.1"
|
||||||
# panic-semihosting = "0.1.0"
|
# panic-semihosting = "0.1.1"
|
||||||
|
panic-semihosting = { git = "https://github.com/japaric/panic-semihosting", branch = "stable" }
|
||||||
# Uncomment for the allocator example.
|
# Uncomment for the allocator example.
|
||||||
#alloc-cortex-m = "0.3.3"
|
#alloc-cortex-m = "0.3.3"
|
||||||
|
|
||||||
|
[dependencies.cortex-m]
|
||||||
|
branch = "stable"
|
||||||
|
default-features = false
|
||||||
|
git = "https://github.com/japaric/cortex-m"
|
||||||
|
# version = "0.4.4"
|
||||||
|
|
||||||
[dependencies.cortex-m-semihosting]
|
[dependencies.cortex-m-semihosting]
|
||||||
default-features = false
|
default-features = false
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ EOF
|
|||||||
|
|
||||||
local examples=(
|
local examples=(
|
||||||
crash
|
crash
|
||||||
|
exception
|
||||||
hello
|
hello
|
||||||
override-exception-handler
|
minimal
|
||||||
panic
|
panic
|
||||||
)
|
)
|
||||||
for ex in "${examples[@]}"; do
|
for ex in "${examples[@]}"; do
|
||||||
|
|||||||
@@ -8,78 +8,104 @@
|
|||||||
//! debugger using these commands:
|
//! debugger using these commands:
|
||||||
//!
|
//!
|
||||||
//! ``` text
|
//! ``` text
|
||||||
|
//! (gdb) continue
|
||||||
|
//! Program received signal SIGTRAP, Trace/breakpoint trap.
|
||||||
|
//! __bkpt () at asm/bkpt.s:3
|
||||||
|
//! 3 bkpt
|
||||||
|
//!
|
||||||
|
//! (gdb) finish
|
||||||
|
//! Run till exit from #0 __bkpt () at asm/bkpt.s:3
|
||||||
|
//! Note: automatically using hardware breakpoints for read-only addresses.
|
||||||
|
//! crash::hf (_ef=0x20004fa0) at examples/crash.rs:102
|
||||||
|
//! 99 asm::bkpt();
|
||||||
|
//!
|
||||||
//! (gdb) # Exception frame = program state during the crash
|
//! (gdb) # Exception frame = program state during the crash
|
||||||
//! (gdb) print/x *ef
|
//! (gdb) print/x *_ef
|
||||||
//! $1 = cortex_m::exception::ExceptionFrame {
|
//! $1 = cortex_m_rt::ExceptionFrame {
|
||||||
//! r0 = 0x2fffffff,
|
//! r0: 0x2fffffff,
|
||||||
//! r1 = 0x2fffffff,
|
//! r1: 0x2fffffff,
|
||||||
//! r2 = 0x0,
|
//! r2: 0x80006b0,
|
||||||
//! r3 = 0x0,
|
//! r3: 0x80006b0,
|
||||||
//! r12 = 0x0,
|
//! r12: 0x20000000,
|
||||||
//! lr = 0x8000481,
|
//! lr: 0x800040f,
|
||||||
//! pc = 0x8000460,
|
//! pc: 0x800066a,
|
||||||
//! xpsr = 0x61000000,
|
//! xpsr: 0x61000000
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! (gdb) # Where did we come from?
|
//! (gdb) # Where did we come from?
|
||||||
//! (gdb) backtrace
|
//! (gdb) backtrace
|
||||||
//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..)
|
//! #0 crash::hf (_ef=0x20004fa0) at examples/crash.rs:102
|
||||||
//! #1 <signal handler called>
|
//! #1 0x080004ac in UserHardFault (ef=0x20004fa0) at <exception macros>:9
|
||||||
//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..)
|
//! #2 <signal handler called>
|
||||||
//! #3 0x08000480 in crash::main () at examples/crash.rs:68
|
//! #3 0x0800066a in core::ptr::read_volatile (src=0x2fffffff) at /checkout/src/libcore/ptr.rs:452
|
||||||
|
//! #4 0x0800040e in crash::main () at examples/crash.rs:85
|
||||||
|
//! #5 0x08000456 in main () at <main macros>:3
|
||||||
//!
|
//!
|
||||||
//! (gdb) # Nail down the location of the crash
|
//! (gdb) # Nail down the location of the crash
|
||||||
//! (gdb) disassemble/m ef.pc
|
//! (gdb) disassemble/m _ef.pc
|
||||||
//! Dump of assembler code for function core::ptr::read_volatile<u32>:
|
//! Dump of assembler code for function core::ptr::read_volatile:
|
||||||
//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
//! 451 pub unsafe fn read_volatile<T>(src: *const T) -> T {}
|
||||||
//! 0x08000454 <+0>: sub sp, #20
|
//! 0x08000662 <+0>: sub sp, #16
|
||||||
//! 0x08000456 <+2>: mov r1, r0
|
//! 0x08000664 <+2>: mov r1, r0
|
||||||
//! 0x08000458 <+4>: str r0, [sp, #8]
|
//! 0x08000666 <+4>: str r0, [sp, #8]
|
||||||
//! 0x0800045a <+6>: ldr r0, [sp, #8]
|
|
||||||
//! 0x0800045c <+8>: str r0, [sp, #12]
|
|
||||||
//!
|
//!
|
||||||
//! 409 intrinsics::volatile_load(src)
|
//! 452 intrinsics::volatile_load(src)
|
||||||
//! 0x0800045e <+10>: ldr r0, [sp, #12]
|
//! 0x08000668 <+6>: ldr r0, [sp, #8]
|
||||||
//! 0x08000460 <+12>: ldr r0, [r0, #0]
|
//! 0x0800066a <+8>: ldr r0, [r0, #0]
|
||||||
//! 0x08000462 <+14>: str r0, [sp, #16]
|
//! 0x0800066c <+10>: str r0, [sp, #12]
|
||||||
//! 0x08000464 <+16>: ldr r0, [sp, #16]
|
//! 0x0800066e <+12>: ldr r0, [sp, #12]
|
||||||
//! 0x08000466 <+18>: str r1, [sp, #4]
|
//! 0x08000670 <+14>: str r1, [sp, #4]
|
||||||
//! 0x08000468 <+20>: str r0, [sp, #0]
|
//! 0x08000672 <+16>: str r0, [sp, #0]
|
||||||
//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24>
|
//! 0x08000674 <+18>: b.n 0x8000676 <core::ptr::read_volatile+20>
|
||||||
//!
|
//!
|
||||||
//! 410 }
|
//! 453 }
|
||||||
//! 0x0800046c <+24>: ldr r0, [sp, #0]
|
//! 0x08000676 <+20>: ldr r0, [sp, #0]
|
||||||
//! 0x0800046e <+26>: add sp, #20
|
//! 0x08000678 <+22>: add sp, #16
|
||||||
//! 0x08000470 <+28>: bx lr
|
//! 0x0800067a <+24>: bx lr
|
||||||
//!
|
//!
|
||||||
//! End of assembler dump.
|
//! End of assembler dump.
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ---
|
//! ---
|
||||||
|
|
||||||
#![feature(used)]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
extern crate cortex_m_rt;
|
#[macro_use]
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
extern crate panic_abort; // panicking behavior
|
extern crate panic_abort; // panicking behavior
|
||||||
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
use cortex_m::asm;
|
use cortex_m::asm;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
fn main() {
|
main!(main);
|
||||||
// Read an invalid memory address
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn main() -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::read_volatile(0x2FFF_FFFF as *const u32);
|
ptr::read_volatile(0x2FFF_FFFF as *const u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As we are not using interrupts, we just register a dummy catch all handler
|
exception!(DefaultHandler, dh);
|
||||||
#[link_section = ".vector_table.interrupts"]
|
|
||||||
#[used]
|
|
||||||
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
|
|
||||||
|
|
||||||
extern "C" fn default_handler() {
|
#[inline(always)]
|
||||||
|
fn dh(_nr: u8) {
|
||||||
asm::bkpt();
|
asm::bkpt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupts!(DefaultHandler);
|
||||||
|
|||||||
69
examples/exception.rs
Normal file
69
examples/exception.rs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
//! Overriding an exception handler
|
||||||
|
//!
|
||||||
|
//! You can override an exception handler using the [`exception!`][1] macro.
|
||||||
|
//!
|
||||||
|
//! [1]: https://docs.rs/cortex-m-rt/0.5.0/cortex_m_rt/macro.exception.html
|
||||||
|
//!
|
||||||
|
//! ---
|
||||||
|
|
||||||
|
#![deny(unsafe_code)]
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cortex_m;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
|
extern crate cortex_m_semihosting as sh;
|
||||||
|
extern crate panic_abort;
|
||||||
|
|
||||||
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use cortex_m::peripheral::syst::SystClkSource;
|
||||||
|
use cortex_m::{asm, Peripherals};
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
use sh::hio::{self, HStdout};
|
||||||
|
|
||||||
|
main!(main);
|
||||||
|
|
||||||
|
fn main() -> ! {
|
||||||
|
let p = Peripherals::take().unwrap();
|
||||||
|
let mut syst = p.SYST;
|
||||||
|
|
||||||
|
syst.set_clock_source(SystClkSource::Core);
|
||||||
|
syst.set_reload(8_000_000); // 1s
|
||||||
|
syst.enable_counter();
|
||||||
|
syst.enable_interrupt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try commenting out this line: you'll end in `deh` instead of in `sys_tick`
|
||||||
|
exception!(SysTick, sys_tick, state: Option<HStdout> = None);
|
||||||
|
|
||||||
|
fn sys_tick(state: &mut Option<HStdout>) {
|
||||||
|
if state.is_none() {
|
||||||
|
*state = Some(hio::hstdout().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(hstdout) = state.as_mut() {
|
||||||
|
hstdout.write_str(".").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(DefaultHandler, deh);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn deh(_nr: u8) {
|
||||||
|
asm::bkpt();
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupts!(DefaultHandler);
|
||||||
@@ -2,17 +2,19 @@
|
|||||||
//!
|
//!
|
||||||
//! ---
|
//! ---
|
||||||
|
|
||||||
#![feature(asm)]
|
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cortex_m;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cortex_m_rt;
|
extern crate cortex_m_rt as rt;
|
||||||
extern crate cortex_m_semihosting as sh;
|
extern crate cortex_m_semihosting as sh;
|
||||||
extern crate panic_abort; // panicking behavior
|
extern crate panic_abort; // panicking behavior
|
||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use cortex_m::asm;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
use sh::hio;
|
use sh::hio;
|
||||||
|
|
||||||
main!(main);
|
main!(main);
|
||||||
@@ -26,7 +28,17 @@ fn main() -> ! {
|
|||||||
|
|
||||||
exception!(DefaultHandler, dh);
|
exception!(DefaultHandler, dh);
|
||||||
|
|
||||||
fn dh(_nr: u8) -> ! {
|
#[inline(always)]
|
||||||
|
fn dh(_nr: u8) {
|
||||||
|
asm::bkpt();
|
||||||
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,28 +12,44 @@
|
|||||||
//!
|
//!
|
||||||
//! ---
|
//! ---
|
||||||
|
|
||||||
#![feature(used)]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
extern crate cortex_m_rt;
|
#[macro_use]
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
extern crate panic_abort; // panicking behavior
|
extern crate panic_abort; // panicking behavior
|
||||||
|
|
||||||
use cortex_m::{asm, Peripherals};
|
use cortex_m::{asm, Peripherals};
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
fn main() {
|
main!(main);
|
||||||
let p = Peripherals::take().unwrap();
|
|
||||||
let mut itm = p.ITM;
|
|
||||||
|
|
||||||
iprintln!(&mut itm.stim[0], "Hello, world!");
|
#[inline(always)]
|
||||||
|
fn main() -> ! {
|
||||||
|
let mut p = Peripherals::take().unwrap();
|
||||||
|
let stim = &mut p.ITM.stim[0];
|
||||||
|
|
||||||
|
iprintln!(stim, "Hello, world!");
|
||||||
|
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As we are not using interrupts, we just register a dummy catch all handler
|
exception!(DefaultHandler, dh);
|
||||||
#[link_section = ".vector_table.interrupts"]
|
|
||||||
#[used]
|
|
||||||
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
|
|
||||||
|
|
||||||
extern "C" fn default_handler() {
|
#[inline(always)]
|
||||||
|
fn dh(_nr: u8) {
|
||||||
asm::bkpt();
|
asm::bkpt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupts!(DefaultHandler);
|
||||||
|
|||||||
@@ -1,34 +1,40 @@
|
|||||||
#![no_main] // <- IMPORTANT!
|
#![no_main] // <- IMPORTANT!
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cortex_m;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cortex_m_rt;
|
extern crate cortex_m_rt as rt;
|
||||||
extern crate panic_abort;
|
extern crate panic_abort;
|
||||||
|
|
||||||
use core::ptr;
|
use cortex_m::asm;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
// user entry point
|
// user entry point
|
||||||
main!(main);
|
main!(main);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
loop {
|
asm::bkpt();
|
||||||
unsafe {
|
|
||||||
// NOTE side affect to avoid UB
|
loop {}
|
||||||
ptr::read_volatile(0x2000_0000 as *const u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// define the default exception handler
|
// define the default exception handler
|
||||||
exception!(DefaultHandler, deh);
|
exception!(DefaultHandler, deh);
|
||||||
|
|
||||||
fn deh(_nr: u8) -> ! {
|
#[inline(always)]
|
||||||
loop {
|
fn deh(_nr: u8) {
|
||||||
unsafe {
|
asm::bkpt();
|
||||||
// NOTE side affect to avoid UB
|
|
||||||
ptr::read_volatile(0x2000_0004 as *const u32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// define the hard fault handler
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind all interrupts to the default exception handler
|
// bind all interrupts to the default exception handler
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
//! Overriding an exception handler
|
|
||||||
//!
|
|
||||||
//! You can override an exception handler using the [`exception!`][1] macro.
|
|
||||||
//!
|
|
||||||
//! [1]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.exception.html
|
|
||||||
//!
|
|
||||||
//! The default exception handler can be overridden using the [`default_handler!`][2] macro
|
|
||||||
//!
|
|
||||||
//! [2]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.default_handler.html
|
|
||||||
//!
|
|
||||||
//! ---
|
|
||||||
|
|
||||||
#![feature(used)]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
extern crate cortex_m;
|
|
||||||
#[macro_use(exception)]
|
|
||||||
extern crate cortex_m_rt;
|
|
||||||
extern crate panic_abort; // panicking behavior
|
|
||||||
|
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
use cortex_m::asm;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
unsafe {
|
|
||||||
// Invalid memory access
|
|
||||||
ptr::read_volatile(0x2FFF_FFFF as *const u32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exception!(HARD_FAULT, handler);
|
|
||||||
|
|
||||||
fn handler() {
|
|
||||||
// You'll hit this breakpoint rather than the one in cortex-m-rt
|
|
||||||
asm::bkpt()
|
|
||||||
}
|
|
||||||
|
|
||||||
// As we are not using interrupts, we just register a dummy catch all handler
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[used]
|
|
||||||
#[link_section = ".vector_table.interrupts"]
|
|
||||||
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
|
|
||||||
|
|
||||||
extern "C" fn default_handler() {
|
|
||||||
asm::bkpt();
|
|
||||||
}
|
|
||||||
@@ -7,25 +7,39 @@
|
|||||||
//!
|
//!
|
||||||
//! ---
|
//! ---
|
||||||
|
|
||||||
#![feature(used)]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
extern crate cortex_m_rt;
|
#[macro_use]
|
||||||
|
extern crate cortex_m_rt as rt;
|
||||||
// extern crate panic_abort;
|
// extern crate panic_abort;
|
||||||
extern crate panic_semihosting; // reports panic messages to the host stderr using semihosting
|
extern crate panic_semihosting; // reports panic messages to the host stderr using semihosting
|
||||||
|
|
||||||
use cortex_m::asm;
|
use cortex_m::asm;
|
||||||
|
use rt::ExceptionFrame;
|
||||||
|
|
||||||
fn main() {
|
main!(main);
|
||||||
panic!("Oops");
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn main() -> ! {
|
||||||
|
panic!("Oops")
|
||||||
}
|
}
|
||||||
|
|
||||||
// As we are not using interrupts, we just register a dummy catch all handler
|
exception!(DefaultHandler, deh);
|
||||||
#[link_section = ".vector_table.interrupts"]
|
|
||||||
#[used]
|
|
||||||
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
|
|
||||||
|
|
||||||
extern "C" fn default_handler() {
|
#[inline(always)]
|
||||||
|
fn deh(_nr: u8) {
|
||||||
asm::bkpt();
|
asm::bkpt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exception!(HardFault, hf);
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||||
|
asm::bkpt();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interrupts!(DefaultHandler);
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ set -ex
|
|||||||
|
|
||||||
main() {
|
main() {
|
||||||
local examples=(
|
local examples=(
|
||||||
|
minimal
|
||||||
hello
|
hello
|
||||||
itm
|
itm
|
||||||
panic
|
panic
|
||||||
crash
|
crash
|
||||||
override-exception-handler
|
exception
|
||||||
device
|
device
|
||||||
allocator
|
allocator
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user