diff --git a/.cargo/config b/.cargo/config index d967978..2f4d0ad 100644 --- a/.cargo/config +++ b/.cargo/config @@ -2,34 +2,38 @@ runner = 'arm-none-eabi-gdb' rustflags = [ "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", - "-Z", "thinlto=no", + "-C", "linker=lld", + "-Z", "linker-flavor=ld.lld", + # "-C", "linker=arm-none-eabi-ld", + # "-Z", "linker-flavor=ld", ] [target.thumbv7m-none-eabi] runner = 'arm-none-eabi-gdb' rustflags = [ "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", - "-Z", "thinlto=no", + "-C", "linker=lld", + "-Z", "linker-flavor=ld.lld", + # "-C", "linker=arm-none-eabi-ld", + # "-Z", "linker-flavor=ld", ] [target.thumbv7em-none-eabi] runner = 'arm-none-eabi-gdb' rustflags = [ "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", - "-Z", "thinlto=no", + "-C", "linker=lld", + "-Z", "linker-flavor=ld.lld", + # "-C", "linker=arm-none-eabi-ld", + # "-Z", "linker-flavor=ld", ] [target.thumbv7em-none-eabihf] runner = 'arm-none-eabi-gdb' rustflags = [ "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", - "-Z", "thinlto=no", + "-C", "linker=lld", + "-Z", "linker-flavor=ld.lld", + # "-C", "linker=arm-none-eabi-ld", + # "-Z", "linker-flavor=ld", ] diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b319b9f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,43 @@ +language: rust + +matrix: + include: + - env: TARGET=thumbv6m-none-eabi + rust: nightly + + - env: TARGET=thumbv7m-none-eabi + rust: nightly + + - env: TARGET=thumbv7em-none-eabi + rust: nightly + + - env: TARGET=thumbv7em-none-eabihf + rust: nightly + +before_install: set -e + +install: + - bash ci/install.sh + +script: + - bash ci/script.sh + +after_script: set +e + +after_success: + - bash ci/after_success.sh + +cache: cargo + +before_cache: + # Travis can't cache files that are not readable by "others" + - chmod -R a+r $HOME/.cargo + +branches: + only: + - staging + - trying + +notifications: + email: + on_success: never diff --git a/CHANGELOG.md b/CHANGELOG.md index be0522f..2a1cfc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.2.7] - 2018-04-24 + +### Changed + +- Bumped the dependency of `cortex-m-rt` to v0.4.0. + ## [v0.2.6] - 2018-04-09 ### Changed @@ -143,7 +149,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Initial release -[Unreleased]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.6...HEAD +[Unreleased]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.7...HEAD +[v0.2.7]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.6...v0.2.7 [v0.2.6]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.5...v0.2.6 [v0.2.5]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.4...v0.2.5 [v0.2.4]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.3...v0.2.4 diff --git a/Cargo.toml b/Cargo.toml index a0fc4c8..a43c206 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,25 +6,24 @@ keywords = ["arm", "cortex-m", "template"] license = "MIT OR Apache-2.0" name = "cortex-m-quickstart" repository = "https://github.com/japaric/cortex-m-quickstart" -version = "0.2.6" +version = "0.2.7" [dependencies] cortex-m = "0.4.0" +cortex-m-rt = "0.4.0" cortex-m-semihosting = "0.2.0" -# alloc-cortex-m release doesn't use linked_list_allocator v0.5.0 yet. +panic-abort = "0.1.1" +panic-semihosting = "0.1.0" +panic-itm = "0.1.0" # Uncomment for the allocator example. -#alloc-cortex-m = "0.3.2" - -[dependencies.cortex-m-rt] -version = "0.3.15" -# Comment for the panic example. -features = ["abort-on-panic"] +#alloc-cortex-m = "0.3.3" # Uncomment for the device example. # [dependencies.stm32f103xx] # features = ["rt"] -# version = "0.8.0" +# version = "0.9.0" [profile.release] debug = true lto = true +opt-level = "s" diff --git a/LICENSE-MIT b/LICENSE-MIT index 65a2323..815d6c0 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2017 {{toml-escape author}} +Copyright (c) 2018 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/bors.toml b/bors.toml new file mode 100644 index 0000000..5ccee21 --- /dev/null +++ b/bors.toml @@ -0,0 +1,3 @@ +status = [ + "continuous-integration/travis-ci/push", +] \ No newline at end of file diff --git a/ci/install.sh b/ci/install.sh new file mode 100644 index 0000000..390304b --- /dev/null +++ b/ci/install.sh @@ -0,0 +1,9 @@ +set -euxo pipefail + +main() { + rustup target add $TARGET + + cargo install cargo-edit || true +} + +main diff --git a/ci/script.sh b/ci/script.sh new file mode 100644 index 0000000..922fdd2 --- /dev/null +++ b/ci/script.sh @@ -0,0 +1,57 @@ +set -euxo pipefail + +main() { + local td=$(mktemp -d) + + git clone . $td + pushd $td + + cat >memory.x <<'EOF' +MEMORY +{ + /* NOTE K = KiBi = 1024 bytes */ + FLASH : ORIGIN = 0x08000000, LENGTH = 256K + RAM : ORIGIN = 0x20000000, LENGTH = 40K +} +EOF + + local examples=( + crash + # device + hello + itm + override-exception-handler + panic + ) + for ex in "${examples[@]}"; do + cargo build --target $TARGET --example $ex + cargo build --target $TARGET --example $ex --release + done + + cargo add alloc-cortex-m + + cargo build --target $TARGET --example allocator + cargo build --target $TARGET --example allocator --release + + examples+=( allocator ) + + if [ $TARGET = thumbv7m-none-eabi ]; then + cat >>Cargo.toml <<'EOF' +[dependencies.stm32f103xx] +features = ["rt"] +version = "0.9.0" +EOF + + cargo build --target $TARGET --example device + cargo build --target $TARGET --example device --release + + examples+=( device ) + fi + + IFS=,;eval arm-none-eabi-size target/$TARGET/release/examples/"{${examples[*]}}" + + popd + rm -rf $td +} + +main diff --git a/examples/allocator.rs b/examples/allocator.rs index b39bfe2..01d2a62 100644 --- a/examples/allocator.rs +++ b/examples/allocator.rs @@ -1,7 +1,6 @@ //! How to use the heap and a dynamic memory allocator //! -//! This example depends on the alloc-cortex-m crate so you'll have to add it -//! to your Cargo.toml: +//! This example depends on the alloc-cortex-m crate so you'll have to add it to your Cargo.toml: //! //! ``` text //! # or edit the Cargo.toml file manually @@ -11,8 +10,8 @@ //! --- #![feature(alloc)] -#![feature(used)] #![feature(global_allocator)] +#![feature(used)] #![no_std] // This is the allocator crate; you can use a different one @@ -22,26 +21,27 @@ extern crate alloc; extern crate cortex_m; extern crate cortex_m_rt; extern crate cortex_m_semihosting; +extern crate panic_abort; // panicking behavior use core::fmt::Write; +use alloc_cortex_m::CortexMHeap; use cortex_m::asm; use cortex_m_semihosting::hio; -use alloc_cortex_m::CortexMHeap; #[global_allocator] static ALLOCATOR: CortexMHeap = CortexMHeap::empty(); extern "C" { static mut _sheap: u32; - static mut _eheap: u32; } +const HEAP_SIZE: usize = 1024; // in bytes + fn main() { // Initialize the allocator let start = unsafe { &mut _sheap as *mut u32 as usize }; - let end = unsafe { &mut _eheap as *mut u32 as usize }; - unsafe { ALLOCATOR.init(start, end - start) } + unsafe { ALLOCATOR.init(start, HEAP_SIZE) } // Growable array allocated on the heap let xs = vec![0, 1, 2]; diff --git a/examples/crash.rs b/examples/crash.rs index f006323..e5cd545 100644 --- a/examples/crash.rs +++ b/examples/crash.rs @@ -1,12 +1,11 @@ //! Debugging a crash (exception) //! -//! The `cortex-m-rt` crate provides functionality for this through a default -//! exception handler. When an exception is hit, the default handler will -//! trigger a breakpoint and in this debugging context the stacked registers -//! are accessible. +//! The `cortex-m-rt` crate provides functionality for this through a default exception handler. +//! When an exception is hit, the default handler will trigger a breakpoint and in this debugging +//! context the stacked registers are accessible. //! -//! In you run the example below, you'll be able to inspect the state of your -//! program under the debugger using these commands: +//! In you run the example below, you'll be able to inspect the state of your program under the +//! debugger using these commands: //! //! ``` text //! (gdb) # Exception frame = program state during the crash @@ -63,6 +62,7 @@ extern crate cortex_m; extern crate cortex_m_rt; +extern crate panic_abort; // panicking behavior use core::ptr; diff --git a/examples/device.rs b/examples/device.rs index 4cc8f63..91e6332 100644 --- a/examples/device.rs +++ b/examples/device.rs @@ -1,25 +1,22 @@ //! Using a device crate //! -//! Crates generated using [`svd2rust`] are referred to as device crates. These -//! crates provides an API to access the peripherals of a device. When you -//! depend on one of these crates and the "rt" feature is enabled you don't need -//! link to the cortex-m-rt crate. +//! Crates generated using [`svd2rust`] are referred to as device crates. These crates provides an +//! API to access the peripherals of a device. When you depend on one of these crates and the "rt" +//! feature is enabled you don't need link to the cortex-m-rt crate. //! //! [`svd2rust`]: https://crates.io/crates/svd2rust //! -//! Device crates also provide an `interrupt!` macro to register interrupt -//! handlers. +//! Device crates also provide an `interrupt!` macro to register interrupt handlers. //! -//! This example depends on the [`stm32f103xx`] crate so you'll have to add it -//! to your Cargo.toml. +//! This example depends on the [`stm32f103xx`] crate so you'll have to add it to your Cargo.toml. //! //! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx //! //! ``` -//! $ edit Cargo.toml && cat $_ +//! $ edit Cargo.toml && tail $_ //! [dependencies.stm32f103xx] //! features = ["rt"] -//! version = "0.8.0" +//! version = "0.9.0" //! ``` //! //! --- @@ -29,9 +26,11 @@ #![no_std] extern crate cortex_m; +// extern crate cortex_m_rt; // included in the device crate extern crate cortex_m_semihosting; #[macro_use(exception, interrupt)] extern crate stm32f103xx; +extern crate panic_abort; // panicking behavior use core::cell::RefCell; use core::fmt::Write; @@ -41,11 +40,9 @@ use cortex_m::peripheral::syst::SystClkSource; use cortex_m_semihosting::hio::{self, HStdout}; use stm32f103xx::Interrupt; -static HSTDOUT: Mutex>> = - Mutex::new(RefCell::new(None)); +static HSTDOUT: Mutex>> = Mutex::new(RefCell::new(None)); -static NVIC: Mutex>> = - Mutex::new(RefCell::new(None)); +static NVIC: Mutex>> = Mutex::new(RefCell::new(None)); fn main() { let global_p = cortex_m::Peripherals::take().unwrap(); diff --git a/examples/hello.rs b/examples/hello.rs index a3f0eb4..3d9d8c0 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -8,6 +8,7 @@ extern crate cortex_m; extern crate cortex_m_rt; extern crate cortex_m_semihosting; +extern crate panic_abort; // panicking behavior use core::fmt::Write; diff --git a/examples/itm.rs b/examples/itm.rs index 77f3149..7cb0dc5 100644 --- a/examples/itm.rs +++ b/examples/itm.rs @@ -1,15 +1,14 @@ //! Sends "Hello, world!" through the ITM port 0 //! -//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the -//! microcontroller's SWO pin to the SWD interface. Note that some development -//! boards don't provide this option. +//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the microcontroller's +//! SWO pin to the SWD interface. Note that some development boards don't provide this option. //! //! ITM is much faster than semihosting. Like 4 orders of magnitude or so. //! -//! You'll need [`itmdump`] to receive the message on the host plus you'll need -//! to uncomment the `monitor` commands in the `.gdbinit` file. +//! You'll need [`itmdump`] to receive the message on the host plus you'll need to uncomment the +//! `monitor` commands in the `.gdbinit` file. //! -//! [`itmdump`]: https://docs.rs/itm/0.1.1/itm/ +//! [`itmdump`]: https://docs.rs/itm/0.2.1/itm/ //! //! --- @@ -19,6 +18,7 @@ #[macro_use] extern crate cortex_m; extern crate cortex_m_rt; +extern crate panic_itm; // panicking behavior use cortex_m::{asm, Peripherals}; @@ -27,6 +27,9 @@ fn main() { let mut itm = p.ITM; iprintln!(&mut itm.stim[0], "Hello, world!"); + + // Also prints the panic message to the ITM + panic!("Oops"); } // As we are not using interrupts, we just register a dummy catch all handler diff --git a/examples/override-exception-handler.rs b/examples/override-exception-handler.rs index 8785a2c..43f3080 100644 --- a/examples/override-exception-handler.rs +++ b/examples/override-exception-handler.rs @@ -4,8 +4,7 @@ //! //! [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 +//! 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 //! @@ -17,6 +16,7 @@ extern crate cortex_m; #[macro_use(exception)] extern crate cortex_m_rt; +extern crate panic_abort; // panicking behavior use core::ptr; diff --git a/examples/panic.rs b/examples/panic.rs index 8b2bdef..c3e8002 100644 --- a/examples/panic.rs +++ b/examples/panic.rs @@ -1,53 +1,26 @@ -//! Defining the panic handler +//! Changing the panic handler //! -//! The panic handler can be defined through the `panic_fmt` [language item][1]. -//! Make sure that the "abort-on-panic" feature of the cortex-m-rt crate is -//! disabled to avoid redefining the language item. +//! The easiest way to change the panic handler is to use a different [panic implementation +//! crate][0]. //! -//! [1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html +//! [0]: https://crates.io/keywords/panic-impl //! //! --- -#![feature(core_intrinsics)] -#![feature(lang_items)] #![feature(used)] #![no_std] extern crate cortex_m; extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; -use core::intrinsics; +// extern crate panic_abort; +extern crate panic_semihosting; // reports panic messages to the host stderr using semihosting use cortex_m::asm; -use cortex_m_semihosting::hio; fn main() { panic!("Oops"); } -#[lang = "panic_fmt"] -#[no_mangle] -pub unsafe extern "C" fn rust_begin_unwind( - args: core::fmt::Arguments, - file: &'static str, - line: u32, - col: u32, -) -> ! { - if let Ok(mut stdout) = hio::hstdout() { - write!(stdout, "panicked at '") - .and_then(|_| { - stdout - .write_fmt(args) - .and_then(|_| writeln!(stdout, "', {}:{}:{}", file, line, col)) - }) - .ok(); - } - - intrinsics::abort() -} - // As we are not using interrupts, we just register a dummy catch all handler #[link_section = ".vector_table.interrupts"] #[used] diff --git a/src/examples/_0_hello.rs b/src/examples/_0_hello.rs index 8a6c470..d6c70bf 100644 --- a/src/examples/_0_hello.rs +++ b/src/examples/_0_hello.rs @@ -10,6 +10,7 @@ //! extern crate cortex_m; //! extern crate cortex_m_rt; //! extern crate cortex_m_semihosting; +//! extern crate panic_abort; // panicking behavior //! //! use core::fmt::Write; //! diff --git a/src/examples/_1_itm.rs b/src/examples/_1_itm.rs index 349dc4b..bc5d67c 100644 --- a/src/examples/_1_itm.rs +++ b/src/examples/_1_itm.rs @@ -1,15 +1,14 @@ //! Sends "Hello, world!" through the ITM port 0 //! -//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the -//! microcontroller's SWO pin to the SWD interface. Note that some development -//! boards don't provide this option. +//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the microcontroller's +//! SWO pin to the SWD interface. Note that some development boards don't provide this option. //! //! ITM is much faster than semihosting. Like 4 orders of magnitude or so. //! -//! You'll need [`itmdump`] to receive the message on the host plus you'll need -//! to uncomment the `monitor` commands in the `.gdbinit` file. +//! You'll need [`itmdump`] to receive the message on the host plus you'll need to uncomment the +//! `monitor` commands in the `.gdbinit` file. //! -//! [`itmdump`]: https://docs.rs/itm/0.1.1/itm/ +//! [`itmdump`]: https://docs.rs/itm/0.2.1/itm/ //! //! --- //! @@ -21,6 +20,7 @@ //! #[macro_use] //! extern crate cortex_m; //! extern crate cortex_m_rt; +//! extern crate panic_itm; // panicking behavior //! //! use cortex_m::{asm, Peripherals}; //! @@ -29,6 +29,9 @@ //! let mut itm = p.ITM; //! //! iprintln!(&mut itm.stim[0], "Hello, world!"); +//! +//! // Also prints the panic message to the ITM +//! panic!("Oops"); //! } //! //! // As we are not using interrupts, we just register a dummy catch all handler diff --git a/src/examples/_2_panic.rs b/src/examples/_2_panic.rs index a08d1c8..0ea182b 100644 --- a/src/examples/_2_panic.rs +++ b/src/examples/_2_panic.rs @@ -1,55 +1,28 @@ -//! Defining the panic handler +//! Changing the panic handler //! -//! The panic handler can be defined through the `panic_fmt` [language item][1]. -//! Make sure that the "abort-on-panic" feature of the cortex-m-rt crate is -//! disabled to avoid redefining the language item. +//! The easiest way to change the panic handler is to use a different [panic implementation +//! crate][0]. //! -//! [1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html +//! [0]: https://crates.io/keywords/panic-impl //! //! --- //! //! ``` //! -//! #![feature(core_intrinsics)] -//! #![feature(lang_items)] //! #![feature(used)] //! #![no_std] //! //! extern crate cortex_m; //! extern crate cortex_m_rt; -//! extern crate cortex_m_semihosting; -//! -//! use core::fmt::Write; -//! use core::intrinsics; +//! // extern crate panic_abort; +//! extern crate panic_semihosting; // reports panic messages to the host stderr using semihosting //! //! use cortex_m::asm; -//! use cortex_m_semihosting::hio; //! //! fn main() { //! panic!("Oops"); //! } //! -//! #[lang = "panic_fmt"] -//! #[no_mangle] -//! pub unsafe extern "C" fn rust_begin_unwind( -//! args: core::fmt::Arguments, -//! file: &'static str, -//! line: u32, -//! col: u32, -//! ) -> ! { -//! if let Ok(mut stdout) = hio::hstdout() { -//! write!(stdout, "panicked at '") -//! .and_then(|_| { -//! stdout -//! .write_fmt(args) -//! .and_then(|_| writeln!(stdout, "', {}:{}:{}", file, line, col)) -//! }) -//! .ok(); -//! } -//! -//! intrinsics::abort() -//! } -//! //! // As we are not using interrupts, we just register a dummy catch all handler //! #[link_section = ".vector_table.interrupts"] //! #[used] diff --git a/src/examples/_3_crash.rs b/src/examples/_3_crash.rs index 1aa431e..96b1516 100644 --- a/src/examples/_3_crash.rs +++ b/src/examples/_3_crash.rs @@ -1,12 +1,11 @@ //! Debugging a crash (exception) //! -//! The `cortex-m-rt` crate provides functionality for this through a default -//! exception handler. When an exception is hit, the default handler will -//! trigger a breakpoint and in this debugging context the stacked registers -//! are accessible. +//! The `cortex-m-rt` crate provides functionality for this through a default exception handler. +//! When an exception is hit, the default handler will trigger a breakpoint and in this debugging +//! context the stacked registers are accessible. //! -//! In you run the example below, you'll be able to inspect the state of your -//! program under the debugger using these commands: +//! In you run the example below, you'll be able to inspect the state of your program under the +//! debugger using these commands: //! //! ``` text //! (gdb) # Exception frame = program state during the crash @@ -65,6 +64,7 @@ //! //! extern crate cortex_m; //! extern crate cortex_m_rt; +//! extern crate panic_abort; // panicking behavior //! //! use core::ptr; //! diff --git a/src/examples/_4_override_exception_handler.rs b/src/examples/_4_override_exception_handler.rs index bc07a2a..a7df0c1 100644 --- a/src/examples/_4_override_exception_handler.rs +++ b/src/examples/_4_override_exception_handler.rs @@ -4,8 +4,7 @@ //! //! [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 +//! 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 //! @@ -19,6 +18,7 @@ //! extern crate cortex_m; //! #[macro_use(exception)] //! extern crate cortex_m_rt; +//! extern crate panic_abort; // panicking behavior //! //! use core::ptr; //! diff --git a/src/examples/_5_device.rs b/src/examples/_5_device.rs index 700fedb..06b1723 100644 --- a/src/examples/_5_device.rs +++ b/src/examples/_5_device.rs @@ -1,25 +1,22 @@ //! Using a device crate //! -//! Crates generated using [`svd2rust`] are referred to as device crates. These -//! crates provides an API to access the peripherals of a device. When you -//! depend on one of these crates and the "rt" feature is enabled you don't need -//! link to the cortex-m-rt crate. +//! Crates generated using [`svd2rust`] are referred to as device crates. These crates provides an +//! API to access the peripherals of a device. When you depend on one of these crates and the "rt" +//! feature is enabled you don't need link to the cortex-m-rt crate. //! //! [`svd2rust`]: https://crates.io/crates/svd2rust //! -//! Device crates also provide an `interrupt!` macro to register interrupt -//! handlers. +//! Device crates also provide an `interrupt!` macro to register interrupt handlers. //! -//! This example depends on the [`stm32f103xx`] crate so you'll have to add it -//! to your Cargo.toml. +//! This example depends on the [`stm32f103xx`] crate so you'll have to add it to your Cargo.toml. //! //! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx //! //! ``` -//! $ edit Cargo.toml && cat $_ +//! $ edit Cargo.toml && tail $_ //! [dependencies.stm32f103xx] //! features = ["rt"] -//! version = "0.8.0" +//! version = "0.9.0" //! ``` //! //! --- @@ -31,9 +28,11 @@ //! #![no_std] //! //! extern crate cortex_m; +//! // extern crate cortex_m_rt; // included in the device crate //! extern crate cortex_m_semihosting; //! #[macro_use(exception, interrupt)] //! extern crate stm32f103xx; +//! extern crate panic_abort; // panicking behavior //! //! use core::cell::RefCell; //! use core::fmt::Write; @@ -43,11 +42,9 @@ //! use cortex_m_semihosting::hio::{self, HStdout}; //! use stm32f103xx::Interrupt; //! -//! static HSTDOUT: Mutex>> = -//! Mutex::new(RefCell::new(None)); +//! static HSTDOUT: Mutex>> = Mutex::new(RefCell::new(None)); //! -//! static NVIC: Mutex>> = -//! Mutex::new(RefCell::new(None)); +//! static NVIC: Mutex>> = Mutex::new(RefCell::new(None)); //! //! fn main() { //! let global_p = cortex_m::Peripherals::take().unwrap(); diff --git a/src/examples/_6_allocator.rs b/src/examples/_6_allocator.rs index b7ab6eb..f85a7b5 100644 --- a/src/examples/_6_allocator.rs +++ b/src/examples/_6_allocator.rs @@ -1,7 +1,6 @@ //! How to use the heap and a dynamic memory allocator //! -//! This example depends on the alloc-cortex-m crate so you'll have to add it -//! to your Cargo.toml: +//! This example depends on the alloc-cortex-m crate so you'll have to add it to your Cargo.toml: //! //! ``` text //! # or edit the Cargo.toml file manually @@ -13,8 +12,8 @@ //! ``` //! //! #![feature(alloc)] -//! #![feature(used)] //! #![feature(global_allocator)] +//! #![feature(used)] //! #![no_std] //! //! // This is the allocator crate; you can use a different one @@ -24,26 +23,27 @@ //! extern crate cortex_m; //! extern crate cortex_m_rt; //! extern crate cortex_m_semihosting; +//! extern crate panic_abort; // panicking behavior //! //! use core::fmt::Write; //! +//! use alloc_cortex_m::CortexMHeap; //! use cortex_m::asm; //! use cortex_m_semihosting::hio; -//! use alloc_cortex_m::CortexMHeap; //! //! #[global_allocator] //! static ALLOCATOR: CortexMHeap = CortexMHeap::empty(); //! //! extern "C" { //! static mut _sheap: u32; -//! static mut _eheap: u32; //! } //! +//! const HEAP_SIZE: usize = 1024; // in bytes +//! //! fn main() { //! // Initialize the allocator //! let start = unsafe { &mut _sheap as *mut u32 as usize }; -//! let end = unsafe { &mut _eheap as *mut u32 as usize }; -//! unsafe { ALLOCATOR.init(start, end - start) } +//! unsafe { ALLOCATOR.init(start, HEAP_SIZE) } //! //! // Growable array allocated on the heap //! let xs = vec![0, 1, 2]; diff --git a/src/lib.rs b/src/lib.rs index a7ee000..dca15de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,10 +3,10 @@ //! # Dependencies //! //! - Nightly Rust toolchain newer than `nightly-2018-04-08`: `rustup default nightly` -//! - ARM linker: `sudo apt-get install binutils-arm-none-eabi` (on Ubuntu) //! - Cargo `clone` subcommand: `cargo install cargo-clone` //! - GDB: `sudo apt-get install gdb-arm-none-eabi` (on Ubuntu) //! - OpenOCD: `sudo apt-get install OpenOCD` (on Ubuntu) +//! - [Optional] ARM linker: `sudo apt-get install binutils-arm-none-eabi` (on Ubuntu) //! - [Optional] Cargo `add` subcommand: `cargo install cargo-edit` //! //! # Usage @@ -47,13 +47,14 @@ //! files. //! //! ``` text -//! $ edit memory.x && cat $_ +//! $ cat >memory.x <<'EOF' //! MEMORY //! { //! /* NOTE K = KiBi = 1024 bytes */ //! FLASH : ORIGIN = 0x08000000, LENGTH = 256K //! RAM : ORIGIN = 0x20000000, LENGTH = 40K //! } +//! EOF //! ``` //! //! 5) Optionally, set a default build target @@ -87,7 +88,6 @@ //! 8) Build the application //! //! ``` text -//! $ # NOTE this command requires `arm-none-eabi-ld` to be in $PATH //! $ cargo build --release //! //! $ # sanity check @@ -113,6 +113,26 @@ //! Tag_ABI_FP_16bit_format: IEEE 754 //! ``` //! +//! **NOTE** By default Cargo will use the LLD linker shipped with the Rust toolchain. If you +//! encounter any linking error try to switch to the GNU linker by modifying the `.cargo/config` +//! file as shown below: +//! +//! ``` text +//! 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", "linker=lld", +//! + # "-Z", "linker-flavor=ld.lld", +//! + "-C", "linker=arm-none-eabi-ld", +//! + "-Z", "linker-flavor=ld", +//! "-Z", "thinlto=no", +//! ] +//! ``` +//! //! 9) Flash the program //! //! ``` text @@ -165,7 +185,7 @@ //! Compiling demo v0.1.0 (file:///home/japaric/tmp/demo) //! error: linking with `arm-none-eabi-ld` failed: exit code: 1 //! | -//! = note: "arm-none-eabi-ld" "-L" (..) +//! = note: "lld" "-L" (..) //! = note: arm-none-eabi-ld: address 0xbaaab838 of hello section `.text' is .. //! arm-none-eabi-ld: address 0xbaaab838 of hello section `.text' is .. //! arm-none-eabi-ld: @@ -184,7 +204,7 @@ //! ``` text //! $ cargo build //! (..) -//! Compiling cortex-m-semihosting v0.1.3 +//! Compiling cortex-m-semihosting v0.2.0 //! error[E0463]: can't find crate for `std` //! //! error: aborting due to previous error