drop linker-flavor, port more examples
This commit is contained in:
@@ -1,39 +1,27 @@
|
||||
[target.thumbv6m-none-eabi]
|
||||
runner = 'arm-none-eabi-gdb'
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "linker=lld",
|
||||
"-Z", "linker-flavor=ld.lld",
|
||||
# "-C", "linker=arm-none-eabi-ld",
|
||||
# "-Z", "linker-flavor=ld",
|
||||
"-C", "link-arg=-Wl,-Tlink.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
[target.thumbv7m-none-eabi]
|
||||
runner = 'arm-none-eabi-gdb'
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "linker=lld",
|
||||
"-Z", "linker-flavor=ld.lld",
|
||||
# "-C", "linker=arm-none-eabi-ld",
|
||||
# "-Z", "linker-flavor=ld",
|
||||
"-C", "link-arg=-Wl,-Tlink.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
[target.thumbv7em-none-eabi]
|
||||
runner = 'arm-none-eabi-gdb'
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "linker=lld",
|
||||
"-Z", "linker-flavor=ld.lld",
|
||||
# "-C", "linker=arm-none-eabi-ld",
|
||||
# "-Z", "linker-flavor=ld",
|
||||
"-C", "link-arg=-Wl,-Tlink.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
[target.thumbv7em-none-eabihf]
|
||||
runner = 'arm-none-eabi-gdb'
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "linker=lld",
|
||||
"-Z", "linker-flavor=ld.lld",
|
||||
# "-C", "linker=arm-none-eabi-ld",
|
||||
# "-Z", "linker-flavor=ld",
|
||||
"-C", "link-arg=-Wl,-Tlink.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
]
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
**/*.rs.bk
|
||||
.#*
|
||||
.gdb_history
|
||||
Cargo.lock
|
||||
target/
|
||||
|
||||
13
Cargo.toml
13
Cargo.toml
@@ -9,15 +9,20 @@ repository = "https://github.com/japaric/cortex-m-quickstart"
|
||||
version = "0.2.7"
|
||||
|
||||
[dependencies]
|
||||
# cortex-m = "0.4.0"
|
||||
# cortex-m-rt = "0.4.0"
|
||||
# cortex-m-rt = "0.5.0"
|
||||
cortex-m-rt = { git = "https://github.com/japaric/cortex-m-rt", branch = "stable" }
|
||||
# panic-loop = { path = "../panic-loop" }
|
||||
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.
|
||||
#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]
|
||||
default-features = false
|
||||
version = "0.2.1"
|
||||
|
||||
@@ -17,8 +17,9 @@ EOF
|
||||
|
||||
local examples=(
|
||||
crash
|
||||
exception
|
||||
hello
|
||||
override-exception-handler
|
||||
minimal
|
||||
panic
|
||||
)
|
||||
for ex in "${examples[@]}"; do
|
||||
|
||||
@@ -8,78 +8,104 @@
|
||||
//! debugger using these commands:
|
||||
//!
|
||||
//! ``` 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) 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) print/x *_ef
|
||||
//! $1 = cortex_m_rt::ExceptionFrame {
|
||||
//! r0: 0x2fffffff,
|
||||
//! r1: 0x2fffffff,
|
||||
//! r2: 0x80006b0,
|
||||
//! r3: 0x80006b0,
|
||||
//! r12: 0x20000000,
|
||||
//! lr: 0x800040f,
|
||||
//! pc: 0x800066a,
|
||||
//! 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
|
||||
//! #0 crash::hf (_ef=0x20004fa0) at examples/crash.rs:102
|
||||
//! #1 0x080004ac in UserHardFault (ef=0x20004fa0) at <exception macros>:9
|
||||
//! #2 <signal handler called>
|
||||
//! #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) 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]
|
||||
//! (gdb) disassemble/m _ef.pc
|
||||
//! Dump of assembler code for function core::ptr::read_volatile:
|
||||
//! 451 pub unsafe fn read_volatile<T>(src: *const T) -> T {}
|
||||
//! 0x08000662 <+0>: sub sp, #16
|
||||
//! 0x08000664 <+2>: mov r1, r0
|
||||
//! 0x08000666 <+4>: str r0, [sp, #8]
|
||||
//!
|
||||
//! 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>
|
||||
//! 452 intrinsics::volatile_load(src)
|
||||
//! 0x08000668 <+6>: ldr r0, [sp, #8]
|
||||
//! 0x0800066a <+8>: ldr r0, [r0, #0]
|
||||
//! 0x0800066c <+10>: str r0, [sp, #12]
|
||||
//! 0x0800066e <+12>: ldr r0, [sp, #12]
|
||||
//! 0x08000670 <+14>: str r1, [sp, #4]
|
||||
//! 0x08000672 <+16>: str r0, [sp, #0]
|
||||
//! 0x08000674 <+18>: b.n 0x8000676 <core::ptr::read_volatile+20>
|
||||
//!
|
||||
//! 410 }
|
||||
//! 0x0800046c <+24>: ldr r0, [sp, #0]
|
||||
//! 0x0800046e <+26>: add sp, #20
|
||||
//! 0x08000470 <+28>: bx lr
|
||||
//! 453 }
|
||||
//! 0x08000676 <+20>: ldr r0, [sp, #0]
|
||||
//! 0x08000678 <+22>: add sp, #16
|
||||
//! 0x0800067a <+24>: bx lr
|
||||
//!
|
||||
//! End of assembler dump.
|
||||
//! ```
|
||||
//!
|
||||
//! ---
|
||||
|
||||
#![feature(used)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m;
|
||||
extern crate cortex_m_rt;
|
||||
#[macro_use]
|
||||
extern crate cortex_m_rt as rt;
|
||||
extern crate panic_abort; // panicking behavior
|
||||
|
||||
use core::ptr;
|
||||
|
||||
use cortex_m::asm;
|
||||
use rt::ExceptionFrame;
|
||||
|
||||
fn main() {
|
||||
// Read an invalid memory address
|
||||
main!(main);
|
||||
|
||||
#[inline(always)]
|
||||
fn main() -> ! {
|
||||
unsafe {
|
||||
ptr::read_volatile(0x2FFF_FFFF as *const u32);
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
// 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];
|
||||
exception!(DefaultHandler, dh);
|
||||
|
||||
extern "C" fn default_handler() {
|
||||
#[inline(always)]
|
||||
fn dh(_nr: u8) {
|
||||
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_std]
|
||||
|
||||
extern crate cortex_m;
|
||||
#[macro_use]
|
||||
extern crate cortex_m_rt;
|
||||
extern crate cortex_m_rt as rt;
|
||||
extern crate cortex_m_semihosting as sh;
|
||||
extern crate panic_abort; // panicking behavior
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use cortex_m::asm;
|
||||
use rt::ExceptionFrame;
|
||||
use sh::hio;
|
||||
|
||||
main!(main);
|
||||
@@ -26,7 +28,17 @@ fn main() -> ! {
|
||||
|
||||
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 {}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,28 +12,44 @@
|
||||
//!
|
||||
//! ---
|
||||
|
||||
#![feature(used)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
extern crate cortex_m;
|
||||
extern crate cortex_m_rt;
|
||||
#[macro_use]
|
||||
extern crate cortex_m_rt as rt;
|
||||
extern crate panic_abort; // panicking behavior
|
||||
|
||||
use cortex_m::{asm, Peripherals};
|
||||
use rt::ExceptionFrame;
|
||||
|
||||
fn main() {
|
||||
let p = Peripherals::take().unwrap();
|
||||
let mut itm = p.ITM;
|
||||
main!(main);
|
||||
|
||||
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
|
||||
#[link_section = ".vector_table.interrupts"]
|
||||
#[used]
|
||||
static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240];
|
||||
exception!(DefaultHandler, dh);
|
||||
|
||||
extern "C" fn default_handler() {
|
||||
#[inline(always)]
|
||||
fn dh(_nr: u8) {
|
||||
asm::bkpt();
|
||||
}
|
||||
|
||||
exception!(HardFault, hf);
|
||||
|
||||
#[inline(always)]
|
||||
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||
asm::bkpt();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
interrupts!(DefaultHandler);
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
#![no_main] // <- IMPORTANT!
|
||||
#![no_std]
|
||||
|
||||
extern crate cortex_m;
|
||||
#[macro_use]
|
||||
extern crate cortex_m_rt;
|
||||
extern crate cortex_m_rt as rt;
|
||||
extern crate panic_abort;
|
||||
|
||||
use core::ptr;
|
||||
use cortex_m::asm;
|
||||
use rt::ExceptionFrame;
|
||||
|
||||
// user entry point
|
||||
main!(main);
|
||||
|
||||
#[inline(always)]
|
||||
fn main() -> ! {
|
||||
loop {
|
||||
unsafe {
|
||||
// NOTE side affect to avoid UB
|
||||
ptr::read_volatile(0x2000_0000 as *const u32);
|
||||
}
|
||||
}
|
||||
asm::bkpt();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
// define the default exception handler
|
||||
exception!(DefaultHandler, deh);
|
||||
|
||||
fn deh(_nr: u8) -> ! {
|
||||
loop {
|
||||
unsafe {
|
||||
// NOTE side affect to avoid UB
|
||||
ptr::read_volatile(0x2000_0004 as *const u32);
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn deh(_nr: u8) {
|
||||
asm::bkpt();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@@ -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]
|
||||
|
||||
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_semihosting; // reports panic messages to the host stderr using semihosting
|
||||
|
||||
use cortex_m::asm;
|
||||
use rt::ExceptionFrame;
|
||||
|
||||
fn main() {
|
||||
panic!("Oops");
|
||||
main!(main);
|
||||
|
||||
#[inline(always)]
|
||||
fn main() -> ! {
|
||||
panic!("Oops")
|
||||
}
|
||||
|
||||
// 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];
|
||||
exception!(DefaultHandler, deh);
|
||||
|
||||
extern "C" fn default_handler() {
|
||||
#[inline(always)]
|
||||
fn deh(_nr: u8) {
|
||||
asm::bkpt();
|
||||
}
|
||||
|
||||
exception!(HardFault, hf);
|
||||
|
||||
#[inline(always)]
|
||||
fn hf(_ef: &ExceptionFrame) -> ! {
|
||||
asm::bkpt();
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
interrupts!(DefaultHandler);
|
||||
|
||||
@@ -5,11 +5,12 @@ set -ex
|
||||
|
||||
main() {
|
||||
local examples=(
|
||||
minimal
|
||||
hello
|
||||
itm
|
||||
panic
|
||||
crash
|
||||
override-exception-handler
|
||||
exception
|
||||
device
|
||||
allocator
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user