From 8e79d05cc4b1014ab9f1e9e966e76525749eb048 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 26 Apr 2018 05:25:27 +0200 Subject: [PATCH] drop linker-flavor, port more examples --- .cargo/config | 28 ++----- .gitignore | 1 + Cargo.toml | 13 ++- ci/script.sh | 3 +- examples/crash.rs | 112 +++++++++++++++---------- examples/exception.rs | 69 +++++++++++++++ examples/hello.rs | 18 +++- examples/itm.rs | 38 ++++++--- examples/minimal.rs | 36 ++++---- examples/override-exception-handler.rs | 47 ----------- examples/panic.rs | 32 +++++-- gen-examples.sh | 3 +- 12 files changed, 246 insertions(+), 154 deletions(-) create mode 100644 examples/exception.rs delete mode 100644 examples/override-exception-handler.rs diff --git a/.cargo/config b/.cargo/config index 2f4d0ad..5999ced 100644 --- a/.cargo/config +++ b/.cargo/config @@ -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", ] diff --git a/.gitignore b/.gitignore index 6cda3bd..59a4524 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ **/*.rs.bk +.#* .gdb_history Cargo.lock target/ diff --git a/Cargo.toml b/Cargo.toml index e40dde2..badd70a 100644 --- a/Cargo.toml +++ b/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" diff --git a/ci/script.sh b/ci/script.sh index 82d2e0f..ac47fd8 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -17,8 +17,9 @@ EOF local examples=( crash + exception hello - override-exception-handler + minimal panic ) for ex in "${examples[@]}"; do diff --git a/examples/crash.rs b/examples/crash.rs index e5cd545..1f6ecfb 100644 --- a/examples/crash.rs +++ b/examples/crash.rs @@ -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 -//! #2 0x08000460 in core::ptr::read_volatile (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 :9 +//! #2 +//! #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
:3 //! //! (gdb) # Nail down the location of the crash -//! (gdb) disassemble/m ef.pc -//! Dump of assembler code for function core::ptr::read_volatile: -//! 408 pub unsafe fn read_volatile(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(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 +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 //! -//! 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); diff --git a/examples/exception.rs b/examples/exception.rs new file mode 100644 index 0000000..11ad73f --- /dev/null +++ b/examples/exception.rs @@ -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 = None); + +fn sys_tick(state: &mut Option) { + 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); diff --git a/examples/hello.rs b/examples/hello.rs index a4f1e5d..b9411de 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -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 {} } diff --git a/examples/itm.rs b/examples/itm.rs index f5b9f17..7b21cae 100644 --- a/examples/itm.rs +++ b/examples/itm.rs @@ -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); diff --git a/examples/minimal.rs b/examples/minimal.rs index 1e0932f..5385e2c 100644 --- a/examples/minimal.rs +++ b/examples/minimal.rs @@ -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 diff --git a/examples/override-exception-handler.rs b/examples/override-exception-handler.rs deleted file mode 100644 index 43f3080..0000000 --- a/examples/override-exception-handler.rs +++ /dev/null @@ -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(); -} diff --git a/examples/panic.rs b/examples/panic.rs index c3e8002..951cc05 100644 --- a/examples/panic.rs +++ b/examples/panic.rs @@ -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); diff --git a/gen-examples.sh b/gen-examples.sh index 660607b..a1f55d2 100644 --- a/gen-examples.sh +++ b/gen-examples.sh @@ -5,11 +5,12 @@ set -ex main() { local examples=( + minimal hello itm panic crash - override-exception-handler + exception device allocator )