drop linker-flavor, port more examples

This commit is contained in:
Jorge Aparicio
2018-04-26 05:25:27 +02:00
parent 0e2ec97ce6
commit 8e79d05cc4
12 changed files with 246 additions and 154 deletions

View File

@@ -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
View File

@@ -1,4 +1,5 @@
**/*.rs.bk **/*.rs.bk
.#*
.gdb_history .gdb_history
Cargo.lock Cargo.lock
target/ target/

View File

@@ -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"

View File

@@ -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

View File

@@ -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
View 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);

View File

@@ -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 {}
} }

View File

@@ -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);

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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
) )