From b917d6439bdcd2b0d64bf6fa81108bf8304f7857 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 5 Sep 2018 17:56:17 +0200 Subject: [PATCH 1/2] move code to the 2018 edition closes #1 --- ci/exceptions/app/Cargo.toml | 5 ++++- ci/exceptions/app/src/main.rs | 5 ++--- ci/exceptions/app2/src/main.rs | 5 ++--- ci/exceptions/rt/src/lib.rs | 2 +- ci/main/app/Cargo.toml | 3 +++ ci/main/app2/src/main.rs | 3 +-- ci/main/app3/src/main.rs | 3 +-- ci/main/app4/Cargo.toml | 5 ++++- ci/main/app4/src/main.rs | 5 ++--- ci/main/rt/Cargo.toml | 7 +++++-- ci/main/rt/src/lib.rs | 2 +- ci/main/rt2/src/lib.rs | 2 +- ci/memory-layout/src/main.rs | 2 +- ci/script.sh | 16 ++++++++++++++++ ci/smallest-no-std/Cargo.toml | 5 ++++- ci/smallest-no-std/src/main.rs | 2 +- src/main.md | 13 +++++++++++-- src/preface.md | 17 +++++++++++++++++ src/smallest-no-std.md | 9 +++++++++ 19 files changed, 86 insertions(+), 25 deletions(-) diff --git a/ci/exceptions/app/Cargo.toml b/ci/exceptions/app/Cargo.toml index 93ba3ae..90af755 100644 --- a/ci/exceptions/app/Cargo.toml +++ b/ci/exceptions/app/Cargo.toml @@ -1,7 +1,10 @@ +cargo-features = ["edition"] + [package] +authors = ["Jorge Aparicio "] +edition = "2018" name = "app" version = "0.1.0" -authors = ["Jorge Aparicio "] [dependencies] rt = { path = "../rt" } diff --git a/ci/exceptions/app/src/main.rs b/ci/exceptions/app/src/main.rs index b73d061..d4ca74e 100644 --- a/ci/exceptions/app/src/main.rs +++ b/ci/exceptions/app/src/main.rs @@ -2,11 +2,10 @@ #![no_main] #![no_std] -#[macro_use] -extern crate rt; - use core::intrinsics; +use rt::entry; + entry!(main); fn main() -> ! { diff --git a/ci/exceptions/app2/src/main.rs b/ci/exceptions/app2/src/main.rs index fd134ee..16148e0 100644 --- a/ci/exceptions/app2/src/main.rs +++ b/ci/exceptions/app2/src/main.rs @@ -2,11 +2,10 @@ #![no_main] #![no_std] -#[macro_use] -extern crate rt; - use core::intrinsics; +use rt::entry; + entry!(main); fn main() -> ! { diff --git a/ci/exceptions/rt/src/lib.rs b/ci/exceptions/rt/src/lib.rs index bef9a9e..c906328 100644 --- a/ci/exceptions/rt/src/lib.rs +++ b/ci/exceptions/rt/src/lib.rs @@ -37,7 +37,7 @@ pub unsafe extern "C" fn Reset() -> ! { pub static RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[panic_handler] -fn panic(_panic: &PanicInfo) -> ! { +fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } diff --git a/ci/main/app/Cargo.toml b/ci/main/app/Cargo.toml index 93ba3ae..ed443a8 100644 --- a/ci/main/app/Cargo.toml +++ b/ci/main/app/Cargo.toml @@ -1,4 +1,7 @@ +cargo-features = ["edition"] # <- + [package] +edition = "2018" # <- name = "app" version = "0.1.0" authors = ["Jorge Aparicio "] diff --git a/ci/main/app2/src/main.rs b/ci/main/app2/src/main.rs index 8f4f9ea..d045cfc 100644 --- a/ci/main/app2/src/main.rs +++ b/ci/main/app2/src/main.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] -#[macro_use] -extern crate rt; +use rt::entry; entry!(main); diff --git a/ci/main/app3/src/main.rs b/ci/main/app3/src/main.rs index 70c959d..622e0f3 100644 --- a/ci/main/app3/src/main.rs +++ b/ci/main/app3/src/main.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] -#[macro_use] -extern crate rt; +use rt::entry; entry!(main); diff --git a/ci/main/app4/Cargo.toml b/ci/main/app4/Cargo.toml index a8e9d33..77438ef 100644 --- a/ci/main/app4/Cargo.toml +++ b/ci/main/app4/Cargo.toml @@ -1,7 +1,10 @@ +cargo-features = ["edition"] + [package] +authors = ["Jorge Aparicio "] +edition = "2018" name = "app" version = "0.1.0" -authors = ["Jorge Aparicio "] [dependencies] rt = { path = "../rt2" } diff --git a/ci/main/app4/src/main.rs b/ci/main/app4/src/main.rs index 923f07d..89dcf58 100644 --- a/ci/main/app4/src/main.rs +++ b/ci/main/app4/src/main.rs @@ -2,11 +2,10 @@ #![no_main] #![no_std] -#[macro_use] -extern crate rt; - use core::ptr; +use rt::entry; + entry!(main); static mut DATA: i32 = 1; diff --git a/ci/main/rt/Cargo.toml b/ci/main/rt/Cargo.toml index 8f434a5..63544a4 100644 --- a/ci/main/rt/Cargo.toml +++ b/ci/main/rt/Cargo.toml @@ -1,6 +1,9 @@ +cargo-features = ["edition"] + [package] -name = "rt" -version = "0.1.0" +name = "rt" # <- authors = ["Jorge Aparicio "] +edition = "2018" +version = "0.1.0" [dependencies] diff --git a/ci/main/rt/src/lib.rs b/ci/main/rt/src/lib.rs index 1ecfb29..94e42ff 100644 --- a/ci/main/rt/src/lib.rs +++ b/ci/main/rt/src/lib.rs @@ -19,7 +19,7 @@ pub unsafe extern "C" fn Reset() -> ! { pub static RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[panic_handler] -fn panic(_panic: &PanicInfo) -> ! { +fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } diff --git a/ci/main/rt2/src/lib.rs b/ci/main/rt2/src/lib.rs index eae87ca..0b62609 100644 --- a/ci/main/rt2/src/lib.rs +++ b/ci/main/rt2/src/lib.rs @@ -37,7 +37,7 @@ pub unsafe extern "C" fn Reset() -> ! { pub static RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[panic_handler] -fn panic(_panic: &PanicInfo) -> ! { +fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } diff --git a/ci/memory-layout/src/main.rs b/ci/memory-layout/src/main.rs index 755216f..95358f6 100644 --- a/ci/memory-layout/src/main.rs +++ b/ci/memory-layout/src/main.rs @@ -19,6 +19,6 @@ pub unsafe extern "C" fn Reset() -> ! { pub static RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[panic_handler] -fn panic(_panic: &PanicInfo) -> ! { +fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } diff --git a/ci/script.sh b/ci/script.sh index ffbb501..5ad7839 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -23,6 +23,8 @@ main() { diff app.o.nm \ <(cargo nm -- target/thumbv7m-none-eabi/debug/deps/app-*.o | grep '[0-9]* [^n] ') + edition_check + popd # # memory-layout @@ -38,6 +40,8 @@ main() { qemu_check target/thumbv7m-none-eabi/debug/app + edition_check + popd # # main @@ -47,20 +51,25 @@ main() { pushd app diff app.objdump \ <(cargo objdump --bin app -- -d -no-show-raw-insn) + # disabled because of rust-lang/rust#53964 + # edition_check popd # check that it builds pushd app2 cargo build + edition_check popd pushd app3 cargo build + edition_check popd pushd app4 cargo build qemu_check target/thumbv7m-none-eabi/debug/app + edition_check popd popd @@ -72,16 +81,23 @@ main() { pushd app diff app.vector_table.objdump \ <(cargo objdump --bin app --release -- -s -j .vector_table) + edition_check popd # check that it builds pushd app2 cargo build + edition_check popd popd } +# checks that 2018 idioms are being used +edition_check() { + RUSTFLAGS="-D rust_2018_compatibility -D rust_2018_idioms" cargo check +} + # checks that QEMU doesn't crash and that it produces no error messages qemu_check() { qemu-system-arm \ diff --git a/ci/smallest-no-std/Cargo.toml b/ci/smallest-no-std/Cargo.toml index 32cf091..fc00d34 100644 --- a/ci/smallest-no-std/Cargo.toml +++ b/ci/smallest-no-std/Cargo.toml @@ -1,6 +1,9 @@ +cargo-features = ["edition"] # <- + [package] -authors = ["Jorge Aparicio "] +edition = "2018" # <- name = "app" +authors = ["Jorge Aparicio "] version = "0.1.0" [dependencies] diff --git a/ci/smallest-no-std/src/main.rs b/ci/smallest-no-std/src/main.rs index 861b9f4..619beba 100644 --- a/ci/smallest-no-std/src/main.rs +++ b/ci/smallest-no-std/src/main.rs @@ -5,6 +5,6 @@ use core::panic::PanicInfo; #[panic_handler] -fn panic(_panic: &PanicInfo) -> ! { +fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } diff --git a/src/main.md b/src/main.md index b81a435..aadc248 100644 --- a/src/main.md +++ b/src/main.md @@ -15,11 +15,11 @@ And then rename it to `rt` which stands for "runtime". ``` console $ sed -i s/app/rt/ Cargo.toml -$ head -n2 Cargo.toml +$ head -n5 Cargo.toml ``` ``` toml -{{#include ../ci/main/rt/Cargo.toml:1:2}} +{{#include ../ci/main/rt/Cargo.toml:1:5}} ``` The first change is to have the reset handler call an external `main` function: @@ -67,6 +67,15 @@ $ cargo new --bin app $ cd app +$ # again, don't forget to move the project to the 2018 edition +$ head -n5 Cargo.toml +``` + +``` toml +{{#include ../ci/main/app/Cargo.toml:1:5}} +``` + +``` console $ cargo add rt --path ../rt $ # copy over the config file that sets a default target and tweaks the linker invocation diff --git a/src/preface.md b/src/preface.md index 2a948ec..8203d9c 100644 --- a/src/preface.md +++ b/src/preface.md @@ -42,6 +42,23 @@ nor is access to a Cortex-M microcontroller needed -- all the examples included QEMU. You will, however, need to install the following tools to run and inspect the examples in this book: +- All the code in this book uses the 2018 edition. If you are not familiar with +the 2018 features and idioms check [the edition guide]. Please also note that +until the 2018 edition is officially released you'll have to *manually modify +the Cargo.toml of new projects* to make use the 2018 edition. The required +changes are shown below: + +[the edition guide]: https://rust-lang-nursery.github.io/edition-guide/ + +``` diff ++cargo-features = ["edition"] ++ + [package] ++edition = "2018" + name = "hello" + version = "0.1.0" +``` + - A nightly toolchain from 2018-08-28 or newer. - [`cargo-binutils`](https://github.com/japaric/cargo-binutils). v0.1.2 or newer. diff --git a/src/smallest-no-std.md b/src/smallest-no-std.md index 353d82e..9bf21e5 100644 --- a/src/smallest-no-std.md +++ b/src/smallest-no-std.md @@ -44,6 +44,15 @@ $ cargo new --bin app $ cd app +$ # don't forget to move the project to the 2018 edition +$ head -n5 Cargo.toml +``` + +``` toml +{{#include ../ci/smallest-no-std/Cargo.toml:1:5}} +``` + +``` console $ # modify main.rs so it has these contents $ cat src/main.rs ``` From 508802f482541321c2af508431494d1c91f96023 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 14 Sep 2018 21:57:42 +0200 Subject: [PATCH 2/2] prepare for beta this commit removes features gate from the code and from Cargo.toml it also makes use of the new `--edition` flag to simplify the instructions for creating a new project --- ci/exceptions/app/Cargo.toml | 2 - ci/exceptions/rt/src/lib.rs | 1 - ci/main/app/Cargo.toml | 4 +- ci/main/app4/Cargo.toml | 2 - ci/main/rt/Cargo.toml | 6 +-- ci/main/rt/src/lib.rs | 1 - ci/main/rt2/src/lib.rs | 1 - ci/memory-layout/src/main.rs | 1 - ci/smallest-no-std/Cargo.toml | 4 +- ci/smallest-no-std/src/main.rs | 1 - src/exceptions.md | 45 ++++++++++++--------- src/main.md | 23 ++++------- src/memory-layout.md | 16 ++++---- src/preface.md | 73 ++++++++++++++++++---------------- src/smallest-no-std.md | 15 +++---- 15 files changed, 90 insertions(+), 105 deletions(-) diff --git a/ci/exceptions/app/Cargo.toml b/ci/exceptions/app/Cargo.toml index 90af755..46537ab 100644 --- a/ci/exceptions/app/Cargo.toml +++ b/ci/exceptions/app/Cargo.toml @@ -1,5 +1,3 @@ -cargo-features = ["edition"] - [package] authors = ["Jorge Aparicio "] edition = "2018" diff --git a/ci/exceptions/rt/src/lib.rs b/ci/exceptions/rt/src/lib.rs index c906328..85059a2 100644 --- a/ci/exceptions/rt/src/lib.rs +++ b/ci/exceptions/rt/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/ci/main/app/Cargo.toml b/ci/main/app/Cargo.toml index ed443a8..3e01231 100644 --- a/ci/main/app/Cargo.toml +++ b/ci/main/app/Cargo.toml @@ -1,7 +1,5 @@ -cargo-features = ["edition"] # <- - [package] -edition = "2018" # <- +edition = "2018" name = "app" version = "0.1.0" authors = ["Jorge Aparicio "] diff --git a/ci/main/app4/Cargo.toml b/ci/main/app4/Cargo.toml index 77438ef..4f9421a 100644 --- a/ci/main/app4/Cargo.toml +++ b/ci/main/app4/Cargo.toml @@ -1,5 +1,3 @@ -cargo-features = ["edition"] - [package] authors = ["Jorge Aparicio "] edition = "2018" diff --git a/ci/main/rt/Cargo.toml b/ci/main/rt/Cargo.toml index 63544a4..93686fe 100644 --- a/ci/main/rt/Cargo.toml +++ b/ci/main/rt/Cargo.toml @@ -1,9 +1,7 @@ -cargo-features = ["edition"] - [package] -name = "rt" # <- -authors = ["Jorge Aparicio "] edition = "2018" +name = "rt" # <- version = "0.1.0" +authors = ["Jorge Aparicio "] [dependencies] diff --git a/ci/main/rt/src/lib.rs b/ci/main/rt/src/lib.rs index 94e42ff..f87b01c 100644 --- a/ci/main/rt/src/lib.rs +++ b/ci/main/rt/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/ci/main/rt2/src/lib.rs b/ci/main/rt2/src/lib.rs index 0b62609..3a9b750 100644 --- a/ci/main/rt2/src/lib.rs +++ b/ci/main/rt2/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/ci/memory-layout/src/main.rs b/ci/memory-layout/src/main.rs index 95358f6..84a1ead 100644 --- a/ci/memory-layout/src/main.rs +++ b/ci/memory-layout/src/main.rs @@ -1,4 +1,3 @@ -#![feature(panic_handler)] #![no_main] #![no_std] diff --git a/ci/smallest-no-std/Cargo.toml b/ci/smallest-no-std/Cargo.toml index fc00d34..1df09e1 100644 --- a/ci/smallest-no-std/Cargo.toml +++ b/ci/smallest-no-std/Cargo.toml @@ -1,7 +1,5 @@ -cargo-features = ["edition"] # <- - [package] -edition = "2018" # <- +edition = "2018" name = "app" authors = ["Jorge Aparicio "] version = "0.1.0" diff --git a/ci/smallest-no-std/src/main.rs b/ci/smallest-no-std/src/main.rs index 619beba..8dc88bb 100644 --- a/ci/smallest-no-std/src/main.rs +++ b/ci/smallest-no-std/src/main.rs @@ -1,4 +1,3 @@ -#![feature(panic_handler)] #![no_main] #![no_std] diff --git a/src/exceptions.md b/src/exceptions.md index 14e6182..8376c9b 100644 --- a/src/exceptions.md +++ b/src/exceptions.md @@ -43,11 +43,11 @@ The first thing we'll do is create an array of vectors (pointers to exception ha `rt` crate's code: ``` console -$ sed -n 57,92p ../rt/src/lib.rs +$ sed -n 56,91p ../rt/src/lib.rs ``` ``` rust -{{#include ../ci/exceptions/rt/src/lib.rs:57:92}} +{{#include ../ci/exceptions/rt/src/lib.rs:56:91}} ``` Some of the entries in the vector table are *reserved*; the ARM documentation states that they @@ -63,7 +63,7 @@ $ tail -n4 ../rt/src/lib.rs ``` ``` rust -{{#include ../ci/exceptions/rt/src/lib.rs:94:97}} +{{#include ../ci/exceptions/rt/src/lib.rs:93:97}} ``` ## Linker script side @@ -105,24 +105,31 @@ handler for the respective exception. That's it! The `rt` crate now has support for exception handlers. We can test it out with following application: +> **NOTE**: Turns out it's hard to generate an exception in QEMU. On real +> hardware a read to an invalid memory address (i.e. outside of the Flash and +> RAM regions) would be enough but QEMU happily accepts the operation and +> returns zero. A trap instruction works on both QEMU and hardware but +> unfortunately it's not available on stable so you'll have to temporarily +> switch to nightly to run this and the next example. + ``` rust {{#include ../ci/exceptions/app/src/main.rs}} ``` ``` console (lldb) b DefaultExceptionHandler -Breakpoint 1: where = app`DefaultExceptionHandler at lib.rs:96, address = 0x000000ec +Breakpoint 1: where = app`DefaultExceptionHandler at lib.rs:95, address = 0x000000ec (lldb) continue Process 1 resuming Process 1 stopped * thread #1, stop reason = breakpoint 1.1 - frame #0: 0x000000ec app`DefaultExceptionHandler at lib.rs:96 - 93 - 94 #[no_mangle] - 95 pub extern "C" fn DefaultExceptionHandler() { --> 96 loop {} - 97 } + frame #0: 0x000000ec app`DefaultExceptionHandler at lib.rs:95 + 92 + 93 #[no_mangle] + 94 pub extern "C" fn DefaultExceptionHandler() { +-> 95 loop {} + 96 } ``` And for completeness, here's the disassembly of the optimized version of the program: @@ -220,12 +227,12 @@ You can test it in QEMU Process 1 resuming Process 1 stopped * thread #1, stop reason = breakpoint 1.1 - frame #0: 0x00000044 app`HardFault at main.rs:19 - 16 #[no_mangle] - 17 pub extern "C" fn HardFault() -> ! { - 18 // do something interesting here --> 19 loop {} - 20 } + frame #0: 0x00000044 app`HardFault at main.rs:18 + 15 #[no_mangle] + 16 pub extern "C" fn HardFault() -> ! { + 17 // do something interesting here +-> 18 loop {} + 19 } ``` The program now executes the user defined `HardFault` function instead of the @@ -234,6 +241,8 @@ The program now executes the user defined `HardFault` function instead of the Like our first attempt at a `main` interface, this first implementation has the problem of having no type safety. It's also easy to mistype the name of the exception, but that doesn't produce an error or warning. Instead the user defined handler is simply ignored. Those problems can be fixed using a -macro like the [`exception!`] macro defined in `cortex-m-rt`. +macro like the [`exception!`] macro defined in `cortex-m-rt` v0.5.x or the +[`exception`] attribute in `cortex-m-rt` v0.6.x. -[`exception!`]: https://github.com/japaric/cortex-m-rt/blob/v0.5.1/src/lib.rs#L79 +[`exception!`]: https://github.com/japaric/cortex-m-rt/blob/v0.5.1/src/lib.rs#L792 +[`exception`]: https://github.com/rust-embedded/cortex-m-rt/blob/v0.6.3/macros/src/lib.rs#L254 diff --git a/src/main.md b/src/main.md index aadc248..6aa70ed 100644 --- a/src/main.md +++ b/src/main.md @@ -15,21 +15,21 @@ And then rename it to `rt` which stands for "runtime". ``` console $ sed -i s/app/rt/ Cargo.toml -$ head -n5 Cargo.toml +$ head -n4 Cargo.toml ``` ``` toml -{{#include ../ci/main/rt/Cargo.toml:1:5}} +{{#include ../ci/main/rt/Cargo.toml:1:4}} ``` The first change is to have the reset handler call an external `main` function: ``` console -$ head -n14 src/lib.rs +$ head -n13 src/lib.rs ``` ``` rust -{{#include ../ci/main/rt/src/lib.rs:1:14}} +{{#include ../ci/main/rt/src/lib.rs:1:13}} ``` We also drop the `#![no_main]` attribute has it has no effect on library crates. @@ -63,19 +63,10 @@ The `rt` will take care of giving the program the right memory layout. ``` console $ cd .. -$ cargo new --bin app +$ cargo new --edition 2018 --bin app $ cd app -$ # again, don't forget to move the project to the 2018 edition -$ head -n5 Cargo.toml -``` - -``` toml -{{#include ../ci/main/app/Cargo.toml:1:5}} -``` - -``` console $ cargo add rt --path ../rt $ # copy over the config file that sets a default target and tweaks the linker invocation @@ -113,7 +104,7 @@ $ tail -n12 ../rt/src/lib.rs ``` ``` rust -{{#include ../ci/main/rt/src/lib.rs:26:37}} +{{#include ../ci/main/rt/src/lib.rs:25:37}} ``` Then the application writers can invoke it like this: @@ -224,7 +215,7 @@ $ head -n32 ../rt/src/lib.rs ``` ``` rust -{{#include ../ci/main/rt2/src/lib.rs:1:32}} +{{#include ../ci/main/rt2/src/lib.rs:1:31}} ``` Now end users can directly and indirectly make use of `static` variables without running into diff --git a/src/memory-layout.md b/src/memory-layout.md index ed1e7f2..b8abefb 100644 --- a/src/memory-layout.md +++ b/src/memory-layout.md @@ -246,12 +246,12 @@ $ lldb target/thumbv7m-none-eabi/debug/app (lldb) gdb-remote 3333 Process 1 stopped * thread #1, stop reason = signal SIGTRAP - frame #0: 0x00000008 app`Reset at main.rs:23 - 20 - 21 #[panic_handler] - 22 fn panic(_panic: &PanicInfo) -> ! { --> 23 loop {} - 24 } + frame #0: 0x00000008 app`Reset at main.rs:22 + 19 + 20 #[panic_handler] + 21 fn panic(_panic: &PanicInfo<'_>) -> ! { +-> 22 loop {} + 23 } (lldb) # ^ that source is wrong; the processor is about to execute Reset; see below (lldb) disassemble -frame @@ -259,8 +259,8 @@ app`Reset: -> 0x8 <+0>: sub sp, #0x4 0xa <+2>: movs r0, #0x2a 0xc <+4>: str r0, [sp] - 0xe <+6>: b 0x10 ; <+8> at main.rs:13 - 0x10 <+8>: b 0x10 ; <+8> at main.rs:13 + 0xe <+6>: b 0x10 ; <+8> at main.rs:12 + 0x10 <+8>: b 0x10 ; <+8> at main.rs:12 (lldb) # the SP has the initial value we programmed in the vector table (lldb) print/x $sp diff --git a/src/preface.md b/src/preface.md index 8203d9c..92dee21 100644 --- a/src/preface.md +++ b/src/preface.md @@ -37,49 +37,54 @@ This book mainly targets to two audiences: ### Requirements -This book is self contained. The reader doesn't need to be familiar with the Cortex-M architecture, -nor is access to a Cortex-M microcontroller needed -- all the examples included in this book can be tested in -QEMU. You will, however, need to install the following tools to run and inspect the examples in this +This book is self contained. The reader doesn't need to be familiar with the +Cortex-M architecture, nor is access to a Cortex-M microcontroller needed -- all +the examples included in this book can be tested in QEMU. You will, however, +need to install the following tools to run and inspect the examples in this book: - All the code in this book uses the 2018 edition. If you are not familiar with -the 2018 features and idioms check [the edition guide]. Please also note that -until the 2018 edition is officially released you'll have to *manually modify -the Cargo.toml of new projects* to make use the 2018 edition. The required -changes are shown below: - -[the edition guide]: https://rust-lang-nursery.github.io/edition-guide/ - -``` diff -+cargo-features = ["edition"] -+ - [package] -+edition = "2018" - name = "hello" - version = "0.1.0" -``` + the 2018 features and idioms check [the edition guide]. -- A nightly toolchain from 2018-08-28 or newer. +- Rust 1.30, 1.30-beta, nightly-2018-09-13, or a newer toolchain PLUS ARM + Cortex-M compilation support. -- [`cargo-binutils`](https://github.com/japaric/cargo-binutils). v0.1.2 or newer. +- [`cargo-binutils`](https://github.com/japaric/cargo-binutils). v0.1.4 or newer. - [`cargo-edit`](https://crates.io/crates/cargo-edit). -- The `thumbv7m-none-eabi` target. +- QEMU with support for ARM emulation. The `qemu-system-arm` program must be + installed on your computer. + +- LLDB. GDB with ARM support can also be used, but this book chooses LLDB as + it's more likely that readers that are not into Cortex-M development have + installed LLDB than GDB with ARM support. + +#### Example setup on Ubuntu 18.04 + +``` console +$ # Rust toolchain +$ # If you start from scratch, get rustup from https://rustup.rs/ +$ rustup default beta + +$ rustc -V +rustc 1.30.0-beta (????????? 2018-09-1?) -- QEMU with support for ARM emulation. The `qemu-system-arm` program must be installed on your - computer. The name may differ for non-Debian based distributions. +$ rustup target add thumbv7m-none-eabi -- LLDB. GDB with ARM support can also be used, but this book chooses LLDB as it's more likely that - readers that are not into Cortex-M development have installed LLDB than GDB with ARM support. +$ # cargo-binutils +$ cargo install cargo-binutils - #### Rust toolchain setup on Linux +$ rustup component add llvm-tools-preview - ```bash - rustup default nightly # If you start from scratch, get rustup from https://rustup.rs/ - rustup target add thumbv7m-none-eabi - cargo install cargo-binutils - rustup component add llvm-tools-preview - sudo apt-get install libssl-dev # For Debian based systems (Ubuntu) - cargo install cargo-edit - ``` +$ # cargo-edit +$ sudo apt-get install gcc libssl-dev pkg-config + +$ cargo install cargo-edit + +$ # QEMU +$ sudo apt-get install qemu-system-arm + +$ # LLDB +$ sudo apt-get install lldb +``` diff --git a/src/smallest-no-std.md b/src/smallest-no-std.md index 9bf21e5..0c7f7a4 100644 --- a/src/smallest-no-std.md +++ b/src/smallest-no-std.md @@ -40,16 +40,9 @@ runs on a system. It can be many things that a standard Rust application can nev With that out of the way, we can move on to the smallest `#![no_std]` program that compiles: ``` console -$ cargo new --bin app +$ cargo new --edition 2018 --bin app $ cd app - -$ # don't forget to move the project to the 2018 edition -$ head -n5 Cargo.toml -``` - -``` toml -{{#include ../ci/smallest-no-std/Cargo.toml:1:5}} ``` ``` console @@ -77,8 +70,6 @@ indexing). This program doesn't produce anything useful. In fact, it will produce an empty binary. ``` console -$ cargo rustc --target thumbv7m-none-eabi -- --emit=obj - $ # equivalent to `size target/thumbv7m-none-eabi/debug/app` $ cargo size --target thumbv7m-none-eabi --bin app ``` @@ -87,7 +78,11 @@ $ cargo size --target thumbv7m-none-eabi --bin app {{#include ../ci/smallest-no-std/app.size}} ``` +Before linking the crate does contain the panicking symbol. + ``` console +$ cargo rustc --target thumbv7m-none-eabi -- --emit=obj + $ cargo nm -- target/thumbv7m-none-eabi/debug/deps/app-*.o | grep '[0-9]* [^n] ' ```