diff options
Diffstat (limited to 'cortex-m-rt/src/lib.rs')
-rw-r--r-- | cortex-m-rt/src/lib.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs new file mode 100644 index 0000000..e1ec26f --- /dev/null +++ b/cortex-m-rt/src/lib.rs @@ -0,0 +1,81 @@ +//! Minimal startup / runtime for Cortex-M microcontrollers +//! +//! Provides +//! +//! - Before main initialization of the `.bss` and `.data` sections +//! +//! - An overridable (\*) `panic_fmt` implementation that prints overs the ITM +//! or through semihosting depending on the enabled Cargo feature. +//! +//! - Minimal `start` lang item, to support vanilla `fn main()`. NOTE the +//! processor goes into "reactive" mode (`loop { asm!("wfi") }`) after +//! returning from `main`. +//! +//! (\*) To override the `panic_fmt` implementation, simply create a new +//! `rust_begin_unwind` symbol: +//! +//! ``` +//! #[no_mangle] +//! pub unsafe extern "C" fn rust_begin_unwind( +//! _args: ::core::fmt::Arguments, +//! _file: &'static str, +//! _line: u32, +//! ) -> ! { +//! .. +//! } +//! ``` + +#![deny(missing_docs)] +#![deny(warnings)] +#![feature(asm)] +#![feature(compiler_builtins_lib)] +#![feature(lang_items)] +#![feature(linkage)] +#![no_std] + +#[cfg(feature = "panic-over-itm")] +#[macro_use] +extern crate cortex_m; +extern crate compiler_builtins; +#[cfg(feature = "panic-over-semihosting")] +#[macro_use] +extern crate cortex_m_semihosting; +extern crate r0; + +mod lang_items; + +// TODO make private and use `#[used]` +/// The reset handler +/// +/// This is the entry point of all programs +#[doc(hidden)] +#[export_name = "start"] +pub unsafe extern "C" fn reset_handler() -> ! { + extern "C" { + static mut _ebss: u32; + static mut _sbss: u32; + + static mut _edata: u32; + static mut _sdata: u32; + + static _sidata: u32; + } + + ::r0::zero_bss(&mut _sbss, &mut _ebss); + ::r0::init_data(&mut _sdata, &mut _edata, &_sidata); + + // NOTE `rustc` forces this signature on us. See `src/lang_items.rs` + extern "C" { + fn main(argc: isize, argv: *const *const u8) -> isize; + } + + // Neither `argc` or `argv` make sense in bare metal contexts so we just + // stub them + main(0, ::core::ptr::null()); + + // If `main` returns, then we go into "reactive" mode and attend interrupts + // as they occur. + loop { + asm!("wfi" :::: "volatile"); + } +} |