Crate cortex_m_rt [−] [src]
Minimal startup / runtime for Cortex-M microcontrollers
Features
This crate provides
-
Before main initialization of the
.bss
and.data
sections -
An overridable (*)
panic_fmt
implementation that prints to the ITM or to the host stdout (through semihosting) depending on which Cargo feature has been enabled:"panic-over-itm"
or"panic-over-semihosting"
. -
A minimal
start
lang item, to support vanillafn main()
. NOTE the processor goes into "reactive" mode (loop { asm!("wfi") }
) after returning frommain
. -
An opt-in linker script (
"linker-script"
Cargo feature) that encodes the memory layout of a generic Cortex-M microcontroller. This linker script is missing the definition of the FLASH and RAM memory regions of the device. This missing information must be supplied through amemory.x
linker script of the form:
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 128K
RAM : ORIGIN = 0x20000000, LENGTH = 8K
}
- A default exception handler tailored for debugging and that provides
access to the stacked registers under the debugger. By default, all
exceptions (**) are serviced by this handler but this can be overridden
on a per exception basis by opting out of the "exceptions" Cargo feature
and then defining the following
struct
use cortex_m::exception; #[link_section = ".rodata.exceptions"] #[used] static EXCEPTIONS: exception::Handlers = exception::Handlers { hard_fault: my_override, nmi: another_handler, ..exception::DEFAULT_HANDLERS };
(*) 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, ) -> ! { .. }
(**) All the device specific exceptions, i.e. the interrupts, are left unpopulated. You must fill that part of the vector table by defining the following static (with the right memory layout):
#[link_section = ".rodata.interrupts"] #[used] static INTERRUPTS: SomeStruct = SomeStruct { .. }
Example
$ cargo new --bin app && cd $_
$ cargo add cortex-m cortex-m-rt
$ cat Xargo.toml
[dependencies.core]
[dependencies.compiler_builtins]
features = ["mem"]
git = "https://github.com/rust-lang-nursery/compiler-builtins"
stage = 1
$ cat memory.x
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 128K
RAM : ORIGIN = 0x20000000, LENGTH = 8K
}
$ cat src/main.rs
#![feature(used)] #![no_std] #[macro_use] extern crate cortex_m; extern crate cortex_m_rt; fn main() { hprintln!("Hello, world!"); } #[allow(dead_code)] #[link_section = ".rodata.interrupts"] #[used] static INTERRUPTS: [u32; 240] = [0; 240];
$ xargo rustc --target thumbv7m-none-eabi -- -C link-args='-Tlink.x -nostartfiles'
$ arm-none-eabi-objdump -Cd $(find target -name app) | less
08000000 <_VECTOR_TABLE>:
8000000: 20002000 .word 0x20002000
08000004 <cortex_m_rt::RESET_HANDLER>:
8000004: 08000671 q...
08000008 <cortex_m_rt::EXCEPTIONS>:
8000008: 080005a5 080005bd 08000569 08000599 ........i.......
8000018: 08000581 00000000 00000000 00000000 ................
8000028: 00000000 080005b1 00000000 00000000 ................
8000038: 0800058d 08000575 ....u...