28 Commits
dev ... typos

Author SHA1 Message Date
Michael Droogleever Fortuyn
1587daf5d1 Finish removing rustled 2019-11-30 21:31:41 +01:00
Michael Droogleever Fortuyn
4d631b12aa Add space 2019-11-30 20:58:55 +01:00
Michael Droogleever Fortuyn
72532bcee1 Fix debugging binary name 2019-11-30 20:57:00 +01:00
Michael Droogleever Fortuyn
6ed3b08955 Fix gdbinit name 2019-11-30 20:55:37 +01:00
Michael Droogleever Fortuyn
254312a988 Fix gdb command 2019-11-30 20:48:44 +01:00
Michael Droogleever Fortuyn
4b6be8fb61 Bump microbit 2019-11-23 12:16:22 +01:00
Michael Droogleever Fortuyn
74c52e42b6 Typo: build 2019-11-23 12:07:10 +01:00
Michael Droogleever Fortuyn
74950c7a78 Typo: verify 2019-11-23 11:51:53 +01:00
droogmic
d16c5af8f7 Merge pull request #14 from beagleknight/fix/microbit-display-example
fix: microbit display example
2019-11-22 08:16:44 +01:00
droogmic
d2351e6049 Merge pull request #8 from rossjones/patch-1
Update macOS setup text
2019-11-22 08:16:27 +01:00
David Morcillo
d6e4a70e25 fix: microbit display example 2019-11-05 16:40:48 +01:00
Ross Jones
eeabf6b056 Update macOS setup text
The gcc-arm-embedded cask has been removed in favour of a not-yet-implemented normal homebrew formula.
I've tried the above however (as documented in the linked casks PR) and it works as advertised for now.
2019-10-26 14:57:02 +01:00
droogmic
0fdc235a3c Merge pull request #6 from mogenson/master
fixup serial output example so that it builds correctly
2019-10-16 21:08:14 +02:00
droogmic
aa3cc8bcb3 Merge pull request #7 from dstutman/patch-1
Fixes rust-lld errors when building example
2019-10-16 21:07:47 +02:00
Daniel Stutman
8545dda435 Fixes rust-lld errors when building example
Building the previous main.rs failed with: ERROR(cortex-m-rt): The interrupt vectors are missing.
Including the microbit crate in the example fixes this.
2019-04-20 22:16:56 +02:00
Michael Mogenson
7641877efe Remove unused mut
`gpio` does not need to be mutable. Remove `mut` to silence build
warning.
2019-03-27 11:39:35 -04:00
Michael Mogenson
d37d5726ce write_fmt() method needed for write!() macro
Include `use core::fmt::Write;` in serial example.
2019-03-27 11:37:44 -04:00
droogmic
2e48356a55 Merge pull request #4 from mogenson/master
Fixup Getting Started -> Building page
2019-03-17 10:28:26 +01:00
Michael Mogenson
feec6bfb2a Bump microbit crate version to the latest: ~0.7 2019-03-14 10:49:41 -04:00
Michael Mogenson
78bf6ff538 Remove semicolon after #[entry]
Otherwise you get the following build error:

```
error: expected item after attributes
 --> src/main.rs:8:8
  |
8 | #[entry];
  |        ^
```

This one confused me for awhile.
2019-03-14 10:47:26 -04:00
Michael Mogenson
9c6bcd2ee8 Use panic-halt crate, panic-abort requires nightly toolchain features
When trying to follow the Getting Started->Building instructions, the
`panic-abort` crate throws the following build error on rust stable
version 1.33:

```
   Compiling panic-abort v0.3.1
error[E0554]: #![feature] may not be used on the stable release channel
  --> /home/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-abort-0.3.1/src/lib.rs:22:1
   |
22 | #![feature(core_intrinsics)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
  --> /home/mike/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-abort-0.3.1/src/lib.rs:23:1
   |
23 | #![feature(panic_handler)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0554`.
error: Could not compile `panic-abort`.

To learn more, run the command again with --verbose.
```

Switch to the `panic-halt` crate that builds on stable and provides the
`#[panic_handler]` function necesary to get a minimal successful build.
2019-03-14 10:37:41 -04:00
bors[bot]
c2d5c26e49 Merge #3
3: 201810 updates r=droogmic a=droogmic



Co-authored-by: Michael Droogleever <droogmic@gmail.com>
2018-10-13 21:28:55 +00:00
Michael Droogleever
590efd3cfd fix mdbook broken links 2018-10-13 23:00:57 +02:00
Michael Droogleever
498601c451 bump rust nightly 2018-10-13 22:42:03 +02:00
Michael Droogleever
1edb3b94e3 small fixes 2018-10-13 22:37:28 +02:00
Michael Droogleever
28e7da3ad1 bump mdbook to v0.2.1, fix ci and links 2018-10-13 22:34:32 +02:00
Michael Droogleever
ec59c1c010 fix broken include 2018-10-13 22:10:13 +02:00
Michael Droogleever
da3e868599 2018-10 version bumps and compatibility updates 2018-10-13 21:52:28 +02:00
36 changed files with 200 additions and 450 deletions

View File

@@ -1,9 +1,14 @@
# Configure builds for our target, the micro:bit's architecture
[target.thumbv6m-none-eabi] [target.thumbv6m-none-eabi]
# Execute binary using gdb when calling cargo run
runner = "arm-none-eabi-gdb" runner = "arm-none-eabi-gdb"
# Tweak to the linking process required by the cortex-m-rt crate
rustflags = [ rustflags = [
"-C", "link-arg=-Wl,-Tlink.x", "-C", "link-arg=-Tlink.x",
"-C", "link-arg=-nostartfiles", # The LLD linker is selected by default
#"-C", "linker=arm-none-eabi-ld",
] ]
# Automatically select this target when cargo building this project
[build] [build]
target = "thumbv6m-none-eabi" target = "thumbv6m-none-eabi"

View File

@@ -1,5 +1,5 @@
language: rust language: rust
rust: nightly-2018-08-01 rust: nightly-2018-10-12
addons: addons:
apt: apt:

View File

@@ -1,24 +1,26 @@
set -euxo pipefail set -euxo pipefail
MDBOOK_VER=0.2.1
main() { main() {
if [ "$(mdbook -V)" != "mdbook v0.1.8" ]; then if [ "$(mdbook -V)" != "mdbook v$MDBOOK_VER" ]; then
curl -LSfs https://japaric.github.io/trust/install.sh | \ curl -LSfs https://japaric.github.io/trust/install.sh | \
sh -s -- \ sh -s -- \
--force \ --force \
--git rust-lang-nursery/mdBook \ --git rust-lang-nursery/mdBook \
--tag v0.1.8 \ --tag v$MDBOOK_VER \
--target x86_64-unknown-linux-musl \ --target x86_64-unknown-linux-musl \
|| true || true
fi fi
if [ "$(mdbook -V)" != "mdbook v0.1.8" ]; then if [ "$(mdbook -V)" != "mdbook v$MDBOOK_VER" ]; then
cargo install --target x86_64-unknown-linux-gnu --version 0.1.8 mdbook \ cargo install --target x86_64-unknown-linux-gnu --version $MDBOOK_VER mdbook \
|| true || true
fi fi
if [ "$(mdbook -V)" != "mdbook v0.1.8" ]; then if [ "$(mdbook -V)" != "mdbook v$MDBOOK_VER" ]; then
cargo install --force --target x86_64-unknown-linux-gnu --version 0.1.8 mdbook cargo install --force --target x86_64-unknown-linux-gnu --version $MDBOOK_VER mdbook
fi fi
rustup target add thumbv6m-none-eabi rustup target add thumbv6m-none-eabi

View File

@@ -56,9 +56,11 @@
- [Multiplexing](display/03.02.MULT.md) - [Multiplexing](display/03.02.MULT.md)
- [Full Solution](display/03.03.FULL.md) - [Full Solution](display/03.03.FULL.md)
- [WIP - Sensors and I²C](sensors/00.00.README.md)
- [WIP - Non-blocking](nb/00.00.README.md) - [WIP - Non-blocking](nb/00.00.README.md)
- [WIP - Sensors and I²C](sensors/00.00.README.md) - [WIP - Interrupts](nb/00.00.README.md)
- [WIP - Real time](rtfm/00.00.README.md) - [WIP - Real time](rtfm/00.00.README.md)

View File

@@ -26,7 +26,7 @@ in procedure 'ocd_bouncer'
without root privilege. without root privilege.
- Windows: You are probably missing the USB drivers. - Windows: You are probably missing the USB drivers.
[these instructions]: setup/LINUX.html#udev%20rules [these instructions]: ../setup/LINUX.html#udev%20rules
### can't connect to OpenOCD - "Polling again in X00ms" ### can't connect to OpenOCD - "Polling again in X00ms"
@@ -136,7 +136,7 @@ $ rustup target add thumbv7em-none-eabihf
## Build problems ## Build problems
### `error: language item required, but not found: \`eh_personality\`` ### `error: language item required, but not found: 'eh_personality'`
#### Cause #### Cause
@@ -147,3 +147,14 @@ The `eh_personality` language item is used to implement stack unwinding in case
You need to use the correct target You need to use the correct target
by using `--target thumbv6m-none-eabi` by using `--target thumbv6m-none-eabi`
or modifying `.cargo/config` or modifying `.cargo/config`
### `error: ld: cannot open linker script file memory.x: No such file or directory`
#### Cause
A memory.x file is needed, this specifies memory layout.
#### Fix
Either ask the board support crate maintainer to add memory.x to their crate,
or add a memory.x file to your project.

View File

@@ -3,7 +3,7 @@ name = "display"
version = "0.1.0" version = "0.1.0"
[dependencies] [dependencies]
cortex-m-rt="~0.5" cortex-m-rt="~0.6"
cortex-m-semihosting="~0.3" cortex-m-semihosting="~0.3"
panic-semihosting = "~0.3" panic-semihosting = "~0.5"
microbit="~0.5" microbit="~0.6"

View File

@@ -4,12 +4,10 @@
extern crate panic_semihosting; extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
#[macro_use(entry, exception)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use microbit::hal::delay::Delay; use microbit::hal::delay::Delay;
@@ -20,18 +18,6 @@ use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
exception!(HardFault, hard_fault);
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
type LED = PIN<Output<PushPull>>; type LED = PIN<Output<PushPull>>;
const DEFAULT_DELAY_MS: u32 = 2; const DEFAULT_DELAY_MS: u32 = 2;
@@ -128,7 +114,7 @@ impl Display {
} }
} }
entry!(main); #[entry]
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -1,9 +0,0 @@
[target.thumbv6m-none-eabi]
runner = "arm-none-eabi-gdb"
rustflags = [
"-C", "link-arg=-Wl,-Tlink.x",
"-C", "link-arg=-nostartfiles",
]
[build]
target = "thumbv6m-none-eabi"

View File

@@ -1,9 +1,9 @@
# New Project # New Project
``` shell ``` shell
$ cargo new rustled $ cargo new microrust-start
Created binary (application) `rustled` project Created binary (application) `microrust-start` project
$ cd rustled $ cd microrust-start
Cargo.toml src Cargo.toml src
``` ```
@@ -47,7 +47,7 @@ error[E0463]: can't find crate for `std`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`. For more information about this error, try `rustc --explain E0463`.
error: Could not compile `rustled`. error: Could not compile `microrust-start`.
To learn more, run the command again with --verbose. To learn more, run the command again with --verbose.
``` ```
@@ -75,9 +75,6 @@ fn main() {
``` shell ``` shell
$ cargo build --target thumbv6m-none-eabi $ cargo build --target thumbv6m-none-eabi
```
``` shell
error: cannot find macro `println!` in this scope error: cannot find macro `println!` in this scope
--> src/main.rs:4:5 --> src/main.rs:4:5
| |
@@ -91,11 +88,11 @@ We don't need it at the moment, so we can remove it and try to build again.
## Build 3 ## Build 3
``` shell ``` shell
error: language item required, but not found: `panic_impl` $ cargo build --target thumbv6m-none-eabi
error: `#[panic_handler]` function required, but not found
``` ```
This error, is because the panic macro is unimplemented, This error, is because rustc required a panic handler to be implemented.
when rustc needs it to have an implementation.
### `panic_impl` ### `panic_impl`
@@ -112,15 +109,14 @@ If you have forgotten how to do this, try looking at [the cargo book][cargo].
`Cargo.toml` `Cargo.toml`
``` toml ``` toml
[dependencies] {{#include Cargo.toml:5:6}}
panic-abort = "~0.2"
``` ```
`src/main.rs` `src/main.rs`
``` rust ``` rust
#![no_std] #![no_std]
extern crate panic_abort; extern crate panic_halt;
fn main() { fn main() {
} }
@@ -130,9 +126,6 @@ fn main() {
``` shell ``` shell
$ cargo build --target thumbv6m-none-eabi $ cargo build --target thumbv6m-none-eabi
```
``` shell
error: requires `start` lang_item error: requires `start` lang_item
``` ```
@@ -143,7 +136,7 @@ executing the binary usually has the operating system start by executing the C r
This in turn invokes the Rust runtime, as marked by the `start` language item, This in turn invokes the Rust runtime, as marked by the `start` language item,
which in turn invokes the main function. which in turn invokes the main function.
Having enabled `no_std`, as we are targeting on a microcontroller, Having enabled `no_std`, as we are targeting a microcontroller,
neither the crt0 nor the rust runtime are available, neither the crt0 nor the rust runtime are available,
so even implementing `start` would not help us. so even implementing `start` would not help us.
We need to replace the operating system entry point. We need to replace the operating system entry point.
@@ -172,9 +165,7 @@ At this point we need the help of a board-specific support crate and a few cargo
Let us add a dependency on the board crate for the micro:bit. Let us add a dependency on the board crate for the micro:bit.
``` toml ``` toml
[dependencies] {{#include Cargo.toml:5:7}}
panic-abort = "~0.2"
microbit="~0.5"
``` ```
The microbit crate has 2 notable dependencies: The microbit crate has 2 notable dependencies:
@@ -192,13 +183,15 @@ be implemented by board specific crates.
This crate implements the minimal startup / runtime for Cortex-M microcontrollers. This crate implements the minimal startup / runtime for Cortex-M microcontrollers.
Among other things this crate provides: Among other things this crate provides:
- the `entry!` macro, to define the entry point of the program. - the `#[entry]` attribute, to define the entry point of the program.
- the `exception!` macro, to set or override a processor core exception handler. - a definition of the hard fault handler
- a definition of the default exception handler
This crate requires: This crate requires:
- a definition of the specific microcontroller's memory layout as a memory.x file. - a definition of the specific microcontroller's memory layout as a memory.x file.
- a definition of the hard fault handler fortunately this is usually provided by the board support crates
- a definition of the default exception handler
To use the `#[entry]` attribute, we will need to add this as a dependency.
For more detailed information, For more detailed information,
you can use the helpful [cortex-m-quickstart crate][qs] and [its documentation][doc]. you can use the helpful [cortex-m-quickstart crate][qs] and [its documentation][doc].
@@ -209,7 +202,7 @@ you can use the helpful [cortex-m-quickstart crate][qs] and [its documentation][
## cargo config ## cargo config
Before we go any further, Before we go any further,
we are going to tweak the cargo's configuration by editing `rustled/.cargo/config`. we are going to tweak the cargo's configuration by editing `microrust-start/.cargo/config`.
For more information, you can read [the documentation here][cargoconfig]. For more information, you can read [the documentation here][cargoconfig].
[cargoconfig]: https://doc.rust-lang.org/cargo/reference/config.html [cargoconfig]: https://doc.rust-lang.org/cargo/reference/config.html
@@ -217,19 +210,7 @@ For more information, you can read [the documentation here][cargoconfig].
### `.cargo/config` ### `.cargo/config`
``` toml ``` toml
# Configure builds for our target {{#include ../../.cargo/config}}
[target.thumbv6m-none-eabi]
# Execute binary using gdb
runner = "arm-none-eabi-gdb"
# Tweak to the linking process required by the cortex-m-rt crate
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-nostartfiles",
]
# Automatically select this target when running cargo for this project
[build]
target = "thumbv6m-none-eabi"
``` ```
### arm-none-eabi-gdb ### arm-none-eabi-gdb
@@ -246,9 +227,7 @@ and cargo will automatically add `--target thumbv6m-none-eabi`.
### `Cargo.toml` ### `Cargo.toml`
``` toml ``` toml
[dependencies] {{#include Cargo.toml:5:8}}
panic-abort = "~0.2"
microbit="~0.5"
``` ```
### `src/main.rs` ### `src/main.rs`
@@ -257,9 +236,12 @@ microbit="~0.5"
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate panic_abort; extern crate panic_halt;
extern crate microbit;
entry!(main); use cortex_m_rt::entry;
#[entry]
fn main() { fn main() {
} }
``` ```
@@ -269,22 +251,20 @@ $ cargo build
``` ```
``` shell ``` shell
error[E0308]: mismatched types error: custom attribute panicked
--> src/main.rs:9:1 --> src/main.rs:7:1
| |
8 | entry!(main); 7 | #[entry]
| ^^^^^^^^^^^^^ expected !, found () | ^^^^^^^^
| |
= note: expected type `fn() -> !` = help: message: `#[entry]` function must have signature `[unsafe] fn() -> !`
found type `fn() {main}`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
``` ```
## `!` return type ## `!` return type
A little known rust feature, so I will forgive you if you do not know what this means. A little known rust feature, so I will forgive you if you do not know what this means.
A return type of `!` means that the function cannot return A return type of `!` means that the function cannot return.
An easy way to implement this, is by using an infinite loop. An easy way to implement this is to use an infinite loop.
### `src/main.rs` ### `src/main.rs`
@@ -292,12 +272,12 @@ An easy way to implement this, is by using an infinite loop.
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate panic_abort; extern crate panic_halt;
#[macro_use(entry)]
extern crate microbit; extern crate microbit;
entry!(main); use cortex_m_rt::entry;
#[entry]
fn main() -> ! { fn main() -> ! {
loop {} loop {}
} }
@@ -305,98 +285,19 @@ fn main() -> ! {
## Build 6 ## Build 6
``` shell
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
|
= note: "arm-none-eabi-gcc" "-L" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib" "/home/xxx/rust/rustled/target/thumbv6m-none-eabi/debug/deps/rustled-e6053d34b0422141.2yhvr0tmp69gb94x.rcgu.o" "-o"
# SNIP
"/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcore-fb37a4ea1db1e473.rlib" "-Wl,--end-group" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcompiler_builtins-f2357c0397dd7e0d.rlib" "-Wl,-Tlink.x" "-nostartfiles" "-Wl,-Bdynamic"
= note: /usr/lib/gcc/arm-none-eabi/8.1.0/../../../../arm-none-eabi/bin/ld: cannot open linker script file memory.x: No such file or directory
collect2: error: ld returned 1 exit status
```
A scary error, but if you look closely you will see `cannot open linker script file memory.x: No such file or directory`.
We mentioned something a little earlier about memory.x file.
To save you the hassle of scouring the internet for one or creating your own, you can copy it over into your project:
``` shell
$ cp ../../memory.x ./
```
> Often a board support crate will already include this, so this step will not be necessary.
## Build 7
``` shell
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
|
= note: "arm-none-eabi-gcc" "-L" "/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib" "/home/xxx/rust/rustled/target/thumbv6m-none-eabi/debug/deps/rustled-e6053d34b0422141.2yhvr0tmp69gb94x.rcgu.o" "-o"
# SNIP
"/home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/thumbv6m-none-eabi/lib/libcompiler_builtins-f2357c0397dd7e0d.rlib" "-Wl,-Tlink.x" "-nostartfiles" "-Wl,-Bdynamic"
= note: device.x:1: undefined symbol `DefaultHandler' referenced in expression
collect2: error: ld returned 1 exit status
```
Notice `undefined symbol 'DefaultHandler' referenced in expression`.
We said earlier, as with the memory,
that the hard fault handler and default exception handler both need defining.
### `Cargo.toml`
``` toml
[dependencies]
panic-abort = "~0.2"
cortex-m-rt="~0.5"
microbit="~0.5"
```
### `src/main.rs`
``` rust
#![no_std]
#![no_main]
extern crate panic_abort;
extern crate cortex_m_rt as rt;
#[macro_use(entry, exception)]
extern crate microbit;
use rt::ExceptionFrame;
exception!(HardFault, hard_fault);
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! {
loop {}
}
```
It is all a bit ugly, but fortunately it only needs to be done once.
If you try building now, you should finally be greeted with `Finished`! If you try building now, you should finally be greeted with `Finished`!
``` shell ``` shell
$ cargo build $ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 20.51s Finished dev [unoptimized + debuginfo] target(s) in 0.04s
``` ```
## Build Complete ## Build Complete
As a sanity check, let's verify that the produced executable is actually an ARM binary: As a sanity check, let's verify that the produced executable is actually an ARM binary:
``` console ``` shell
$ file target/thumbv6m-none-eabi/debug/rustled $ file target/thumbv6m-none-eabi/debug/microrust-start
target/thumbv6m-none-eabi/debug/rustled: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped target/thumbv6m-none-eabi/debug/microrust-start: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
^^^ ^^^^ ^^^ ^^^^^
``` ```

View File

@@ -2,7 +2,7 @@
Flashing is the process of moving our program into the microcontroller's (persistent) memory. Once flashed, the microcontroller will execute the flashed program every time it is powered on. Flashing is the process of moving our program into the microcontroller's (persistent) memory. Once flashed, the microcontroller will execute the flashed program every time it is powered on.
In this case, our `rustled` program will be the only program in the microcontroller memory. By this I mean that there's nothing else running on the microcontroller: no OS, no daemon, nothing. `rustled` has full control over the device. This is what is meant by *bare-metal* programming. In this case, our `microrust-start` program will be the only program in the microcontroller memory. By this I mean that there's nothing else running on the microcontroller: no OS, no daemon, nothing. `microrust-start` has full control over the device. This is what is meant by *bare-metal* programming.
<dl> <dl>
<dt>OS</dt> <dt>OS</dt>
@@ -71,8 +71,8 @@ available.
I mentioned that OpenOCD provides a GDB server so let's connect to that right now: I mentioned that OpenOCD provides a GDB server so let's connect to that right now:
``` console ``` console
$ arm-none-eabi-gdb -q target/thumbv6m-none-eabi/debug/rustled $ arm-none-eabi-gdb -q target/thumbv6m-none-eabi/debug/microrust-start
Reading symbols from target/thumbv6m-none-eabi/debug/rustled...done. Reading symbols from target/thumbv6m-none-eabi/debug/microrust-start...done.
(gdb) (gdb)
``` ```
@@ -157,7 +157,7 @@ set print asm-demangle on
# Load your program, breaks at entry # Load your program, breaks at entry
load load
# (optional) Add breakpoint at function # (optional) Add breakpoint at function
break rustled::main break main
# Continue with execution # Continue with execution
continue continue
``` ```

View File

@@ -28,14 +28,14 @@ At this time, we are not interested in that "pre-main" part so let's skip right
the `main` function. We'll do that using a breakpoint: the `main` function. We'll do that using a breakpoint:
``` ```
(gdb) break rustled::main (gdb) break main
Breakpoint 1 at 0x8000218: file src/main.rs, line 8. Breakpoint 1 at 0x8000218: file src/main.rs, line 8.
(gdb) continue (gdb) continue
Continuing. Continuing.
Note: automatically using hardware breakpoints for read-only addresses. Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, rustled::main () at src/rustled/src/main.rs:13 Breakpoint 1, main () at src/microrust-start/src/main.rs:13
13 let x = 42; 13 let x = 42;
``` ```

View File

@@ -17,7 +17,7 @@ This is a recap of what we have done so far.
## `.cargo/config` ## `.cargo/config`
``` toml ``` toml
{{#include .cargo/config}} {{#include ../../.cargo/config}}
``` ```
## `.gdbinit` ## `.gdbinit`

View File

@@ -1,8 +1,8 @@
[package] [package]
name = "start" name = "start"
version = "0.1.0" version = "0.2.0"
[dependencies] [dependencies]
panic-abort = "~0.2" panic-halt = "~0.2"
cortex-m-rt="~0.5" microbit="~0.8"
microbit="~0.5" cortex-m-rt="~0.6"

View File

@@ -1,27 +1,13 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate panic_abort; extern crate cortex_m_rt;
extern crate cortex_m_rt as rt;
#[macro_use(entry, exception)]
extern crate microbit; extern crate microbit;
extern crate panic_halt;
use rt::ExceptionFrame; use cortex_m_rt::entry;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let _y; let _y;
let x = 42; let x = 42;

View File

@@ -2,5 +2,5 @@
In this chapter, we will discuss the basic I/O of embedded development in rust. In this chapter, we will discuss the basic I/O of embedded development in rust.
After this chapter,you should have all the neccesary basic knowledge to do embedded development in Rust, After this chapter, you should have all the neccesary basic knowledge to do embedded development in Rust,
with anything remaining being solution specific. with anything remaining being solution specific.

View File

@@ -18,18 +18,19 @@ The micro:bit allows us to transmit and receive this serial communication over U
To read and write to the serial bus from your computer, you will need to configure your tooling: To read and write to the serial bus from your computer, you will need to configure your tooling:
- [*nix](hello-world/02.01.NIX.html) - [*nix](../hello-world/02.01.NIX.html)
- [Windows](hello-world/02.02.WINDOWS.html) - [Windows](../hello-world/02.02.WINDOWS.html)
## Code ## Code
``` rust ``` rust
use core::fmt::Write;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
// -- snip -- // -- snip --
if let Some(p) = microbit::Peripherals::take() { if let Some(p) = microbit::Peripherals::take() {
let mut gpio = p.GPIO.split(); let gpio = p.GPIO.split();
// Configure RX and TX pins accordingly // Configure RX and TX pins accordingly
let tx = gpio.pin24.into_push_pull_output().downgrade(); let tx = gpio.pin24.into_push_pull_output().downgrade();
let rx = gpio.pin25.into_floating_input().downgrade(); let rx = gpio.pin25.into_floating_input().downgrade();

View File

@@ -12,4 +12,4 @@ You now know enough to start playing around with the micro:bit's LED display and
as well as logging data back to the host. as well as logging data back to the host.
You should know that the microbit crate already includes an abstraction for the LED display for you to use. You should know that the microbit crate already includes an abstraction for the LED display for you to use.
How to implemented a simple blocking display driver is demonstrated in the [LED display chapter](display/00.00.README.html). How to implemented a simple blocking display driver is demonstrated in the [LED display chapter](../display/00.00.README.html).

View File

@@ -1,9 +1,9 @@
[package] [package]
name = "hello" name = "hello"
version = "0.1.0" version = "0.2.0"
[dependencies] [dependencies]
cortex-m-rt="~0.5" microbit="~0.6"
cortex-m-semihosting="" cortex-m-rt="~0.6"
panic-semihosting = "~0.3" cortex-m-semihosting="~0.3"
microbit="~0.5" panic-semihosting = "~0.5"

View File

@@ -4,31 +4,17 @@
extern crate panic_semihosting; extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
#[macro_use(entry, exception)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -1,7 +1,7 @@
# Display # Display
The micro:bit display is not trivial to control, so a driver is needed; The micro:bit display is not trivial to control, so a driver is needed;
see [the display chapter](display/00.00.README.html) for more details. see [the display chapter](../display/00.00.README.html) for more details.
Display calls for now are only blocking, and can either be for binary images (0 for off, 1 for on), Display calls for now are only blocking, and can either be for binary images (0 for off, 1 for on),
or for monochrome images with differing brightness levels or for monochrome images with differing brightness levels

View File

@@ -3,8 +3,8 @@ name = "microbit"
version = "0.1.0" version = "0.1.0"
[dependencies] [dependencies]
cortex-m-rt="~0.5" cortex-m-rt="~0.6"
cortex-m-semihosting="" cortex-m-semihosting="~0.3"
panic-abort = "~0.2" panic-abort = "~0.3"
panic-semihosting = "~0.3" panic-semihosting = "~0.5"
microbit="~0.5" microbit="~0.6"

View File

@@ -3,30 +3,16 @@
extern crate panic_abort; extern crate panic_abort;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
#[macro_use(entry, exception)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
if let Some(p) = microbit::Peripherals::take() { if let Some(p) = microbit::Peripherals::take() {
// Split GPIO // Split GPIO

View File

@@ -3,8 +3,6 @@
extern crate panic_abort; extern crate panic_abort;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
#[macro_use(entry, exception)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
@@ -15,19 +13,7 @@ use microbit::hal::delay::Delay;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
if let Some(p) = microbit::Peripherals::take() { if let Some(p) = microbit::Peripherals::take() {
// Split GPIO // Split GPIO

View File

@@ -8,54 +8,40 @@ extern crate cortex_m_semihosting as sh;
extern crate panic_abort; extern crate panic_abort;
use core::fmt::Write; use core::fmt::Write;
use rt::entry;
use rt::ExceptionFrame;
use microbit::hal::delay::Delay; use microbit::hal::delay::Delay;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
use microbit::led; use microbit::led;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
if let Some(p) = microbit::Peripherals::take() { if let Some(p) = microbit::Peripherals::take() {
let mut gpio = p.GPIO.split(); let mut gpio = p.GPIO.split();
let mut delay = Delay::new(p.TIMER0); let mut delay = Delay::new(p.TIMER0);
// Configure display pins // Configure display pins
let row1 = gpio.pin13.into_push_pull_output().downgrade(); let row1 = gpio.pin13.into_push_pull_output();
let row2 = gpio.pin14.into_push_pull_output().downgrade(); let row2 = gpio.pin14.into_push_pull_output();
let row3 = gpio.pin15.into_push_pull_output().downgrade(); let row3 = gpio.pin15.into_push_pull_output();
let col1 = gpio.pin4.into_push_pull_output().downgrade(); let col1 = gpio.pin4.into_push_pull_output();
let col2 = gpio.pin5.into_push_pull_output().downgrade(); let col2 = gpio.pin5.into_push_pull_output();
let col3 = gpio.pin6.into_push_pull_output().downgrade(); let col3 = gpio.pin6.into_push_pull_output();
let col4 = gpio.pin7.into_push_pull_output().downgrade(); let col4 = gpio.pin7.into_push_pull_output();
let col5 = gpio.pin8.into_push_pull_output().downgrade(); let col5 = gpio.pin8.into_push_pull_output();
let col6 = gpio.pin9.into_push_pull_output().downgrade(); let col6 = gpio.pin9.into_push_pull_output();
let col7 = gpio.pin10.into_push_pull_output().downgrade(); let col7 = gpio.pin10.into_push_pull_output();
let col8 = gpio.pin11.into_push_pull_output().downgrade(); let col8 = gpio.pin11.into_push_pull_output();
let col9 = gpio.pin12.into_push_pull_output().downgrade(); let col9 = gpio.pin12.into_push_pull_output();
// Configure RX and TX pins accordingly // Configure RX and TX pins accordingly
let tx = gpio.pin24.into_push_pull_output().downgrade(); let tx = gpio.pin24.into_push_pull_output().downgrade();
let rx = gpio.pin25.into_floating_input().downgrade(); let rx = gpio.pin25.into_floating_input().downgrade();
let mut leds = led::Display::new( let mut leds = led::Display::new(
row1, row2, row3, col1, col2, col3, col4, col5, col6, col7, col8, col9, col1, col2, col3, col4, col5, col6, col7, col8, col9, row1, row2, row3,
); );
let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split(); let (mut tx, _) = serial::Serial::uart0(p.UART0, tx, rx, BAUD115200).split();

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
[dependencies] [dependencies]
heapless="~0.3" heapless="~0.3"
cortex-m-rt="~0.5" cortex-m-rt="~0.6"
cortex-m-semihosting="" cortex-m-semihosting="~0.3"
panic-semihosting = "~0.3" panic-semihosting = "~0.5"
microbit="~0.5" microbit="~0.6"

View File

@@ -5,12 +5,10 @@ extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
extern crate heapless; extern crate heapless;
#[macro_use(entry, exception, block)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use heapless::{consts, Vec, String}; use heapless::{consts, Vec, String};
@@ -19,19 +17,7 @@ use microbit::hal::delay::Delay;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -5,12 +5,10 @@ extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
extern crate heapless; extern crate heapless;
#[macro_use(entry, exception, block)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use heapless::{consts, Vec, String}; use heapless::{consts, Vec, String};
@@ -19,19 +17,7 @@ use microbit::hal::delay::Delay;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -4,12 +4,10 @@
extern crate panic_semihosting; extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
#[macro_use(entry, exception, block)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use microbit::hal::delay::Delay; use microbit::hal::delay::Delay;
@@ -18,18 +16,6 @@ use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
use microbit::led; use microbit::led;
exception!(HardFault, hard_fault);
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
const WINNING_SCORE: u8 = 6; const WINNING_SCORE: u8 = 6;
const QUESTION_COUNT: u8 = 2*WINNING_SCORE - 1; const QUESTION_COUNT: u8 = 2*WINNING_SCORE - 1;
@@ -49,7 +35,7 @@ const LETTER_B: [[u8; 5]; 5] = [
[0, 1, 1, 0, 0], [0, 1, 1, 0, 0],
]; ];
entry!(main); #[entry]
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -5,12 +5,10 @@ extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
extern crate heapless; extern crate heapless;
#[macro_use(entry, exception, block)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use heapless::{consts, Vec}; use heapless::{consts, Vec};
@@ -19,19 +17,7 @@ use microbit::hal::delay::Delay;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -4,31 +4,18 @@
extern crate panic_semihosting; extern crate panic_semihosting;
extern crate cortex_m_rt as rt; extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh; extern crate cortex_m_semihosting as sh;
#[macro_use(entry, exception, block)]
extern crate microbit; extern crate microbit;
use core::fmt::Write; use core::fmt::Write;
use rt::ExceptionFrame; use rt::entry;
use sh::hio; use sh::hio;
use microbit::hal::prelude::*; use microbit::hal::prelude::*;
use microbit::hal::serial; use microbit::hal::serial;
use microbit::hal::serial::BAUD115200; use microbit::hal::serial::BAUD115200;
use microbit::nb::block;
exception!(HardFault, hard_fault); #[entry]
fn hard_fault(ef: &ExceptionFrame) -> ! {
panic!("{:#?}", ef);
}
exception!(*, default_handler);
fn default_handler(irqn: i16) {
panic!("Unhandled exception (IRQn = {})", irqn);
}
entry!(main);
fn main() -> ! { fn main() -> ! {
let mut stdout = hio::hstdout().unwrap(); let mut stdout = hio::hstdout().unwrap();
writeln!(stdout, "Start").unwrap(); writeln!(stdout, "Start").unwrap();

View File

@@ -85,8 +85,6 @@ $ # ^^^^
If `uucp` appears in the output. You are all set! Go to the [next section]. Otherwise, keep reading: If `uucp` appears in the output. You are all set! Go to the [next section]. Otherwise, keep reading:
[next section]: setup/VERIFY.html
- Add yourself to the `uucp` group. - Add yourself to the `uucp` group.
``` shell ``` shell
@@ -117,3 +115,5 @@ shells *won't* have access to `uucp` devices unless you manually re-log on them
command. command.
Now, go to the [next section]. Now, go to the [next section].
[next section]: ../setup/VERIFY.html

View File

@@ -1,19 +1,18 @@
# macOS # macOS
> UNTESTED: please submit an issue if you can confirm this works.
All the tools can be install using [Homebrew]: All the tools can be install using [Homebrew]:
[Homebrew]: http://brew.sh/ [Homebrew]: http://brew.sh/
``` shell ``` shell
$ brew cask install gcc-arm-embedded $ brew cask install https://raw.githubusercontent.com/Homebrew/homebrew-cask/b88346667547cc85f8f2cacb3dfe7b754c8afc8a/Casks/gcc-arm-embedded.rb
$ brew install minicom openocd $ brew install minicom openocd
``` ```
If the `brew cask` command doesn't work (`Error: Unknown command: cask`), then run `brew tap Unfortunately gcc-arm-embedded has been [removed from Homebrew casks] in an attempt to force somebody to move it to Homebrew, and so it has to be installed using the cask in an earlier commit.
Caskroom/tap` first and try again.
[removed from Homebrew casks]: https://github.com/Homebrew/homebrew-cask/pull/56802
That's all! Go to the [next section]. That's all! Go to the [next section].
[next section]: setup/VERIFY.html [next section]: ../setup/VERIFY.html

View File

@@ -44,18 +44,18 @@ Then, install or switch to the nightly channel.
$ rustup default nightly $ rustup default nightly
``` ```
**NOTE** Make sure you have a nightly newer than `nightly-2018-06-22`. **NOTE** Make sure you have a nightly newer than `nightly-2018-10-12`.
`rustc -V` should return a date newer than the one shown below: `rustc -V` should return a date newer than the one shown below:
``` shell ``` shell
$ rustc -V $ rustc -V
rustc 1.28.0-nightly (056f589fb 2018-06-22) rustc 1.31.0-nightly (2c2e2c57d 2018-10-12)
``` ```
### OS specific instructions ### OS specific instructions
Now follow the instructions specific to the OS you are using: Now follow the instructions specific to the OS you are using:
- [Linux](setup/LINUX.html) - [Linux](../setup/LINUX.html)
- [Windows](setup/WINDOWS.html) - [Windows](../setup/WINDOWS.html)
- [macOS](setup/MACOS.html) - [macOS](../setup/MACOS.html)

View File

@@ -18,7 +18,7 @@ Bus 002 Device 033: ID 0d28:0204 NXP ARM mbed
``` ```
In my case, the micro:bit got connected to the bus #2 and got enumerated as the device #33. In my case, the micro:bit got connected to the bus #2 and got enumerated as the device #33.
This means the file `/dev/bus/usb/002/033` *is* the Fmicro:bit3. This means the file `/dev/bus/usb/002/033` is the micro:bit.
Let's check its permissions: Let's check its permissions:
``` shell ``` shell
@@ -30,7 +30,7 @@ crw-rw---- 1 root uucp 189, 160 Jul 8 14:06 /dev/bus/usb/002/033
The group should be `uucp`. The group should be `uucp`.
If it's not ... then check your [udev rules] and try re-loading them with: If it's not ... then check your [udev rules] and try re-loading them with:
[udev rules]: setup/LINUX.html#udev%20rules [udev rules]: ../setup/LINUX.html#udev%20rules
``` shell ``` shell
$ sudo udevadm control --reload-rules $ sudo udevadm control --reload-rules
@@ -79,7 +79,7 @@ Info : nrf51.cpu: hardware has 4 breakpoints, 2 watchpoints
(If you don't ... then check the [general troubleshooting] instructions.) (If you don't ... then check the [general troubleshooting] instructions.)
[general troubleshooting]: appendix/troubleshooting.html [general troubleshooting]: ../appendix/troubleshooting.html
`openocd` will block the terminal. That's fine. `openocd` will block the terminal. That's fine.

View File

@@ -40,4 +40,4 @@ Download the latest `putty.exe` from [this site] and place it somewhere in your
That's all! Go to the [next section]. That's all! Go to the [next section].
[next section]: setup/VERIFY.html [next section]: ../setup/VERIFY.html

View File

@@ -9,42 +9,36 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" /> <meta name="theme-color" content="#ffffff" />
<base href="{{ path_to_root }}"> <link rel="shortcut icon" href="{{ path_to_root }}{{ favicon }}">
<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
<link rel="stylesheet" href="book.css"> <!-- Fonts -->
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="{{ favicon }}"> <!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
<!-- Font Awesome --> <link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css"> <link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets --> <!-- Custom theme stylesheets -->
{{#each additional_css}} {{#each additional_css}}
<link rel="stylesheet" href="{{this}}"> <link rel="stylesheet" href="{{ this }}">
{{/each}} {{/each}}
{{#if mathjax_support}} {{#if mathjax_support}}
<!-- MathJax --> <!-- MathJax -->
<script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
{{/if}} {{/if}}
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-111729278-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-111729278-2');
</script>
</head> </head>
<body class="light"> <body class="light">
<!-- Provide site root to javascript -->
<script type="text/javascript">var path_to_root = "{{ path_to_root }}";</script>
<!-- Work around some values being stored in localStorage wrapped in quotes --> <!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript"> <script type="text/javascript">
try { try {
@@ -116,7 +110,7 @@
<h1 class="menu-title">{{ book_title }}</h1> <h1 class="menu-title">{{ book_title }}</h1>
<div class="right-buttons"> <div class="right-buttons">
<a href="print.html" class="icon-button" title="Print this book" aria-label="Print this book"> <a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i> <i id="print-button" class="fa fa-print"></i>
</a> </a>
<a href="https://github.com/droogmic/microrust" class="icon-button" title="Go to GitHub repo" aria-label="Link to GitHub repo"> <a href="https://github.com/droogmic/microrust" class="icon-button" title="Go to GitHub repo" aria-label="Link to GitHub repo">
@@ -156,13 +150,13 @@
<nav class="nav-wrapper" aria-label="Page navigation"> <nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons --> <!-- Mobile navigation buttons -->
{{#previous}} {{#previous}}
<a rel="prev" href="{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i> <i class="fa fa-angle-left"></i>
</a> </a>
{{/previous}} {{/previous}}
{{#next}} {{#next}}
<a rel="next" href="{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i> <i class="fa fa-angle-right"></i>
</a> </a>
{{/next}} {{/next}}
@@ -174,13 +168,13 @@
<nav class="nav-wide-wrapper" aria-label="Page navigation"> <nav class="nav-wide-wrapper" aria-label="Page navigation">
{{#previous}} {{#previous}}
<a href="{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <a href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i> <i class="fa fa-angle-left"></i>
</a> </a>
{{/previous}} {{/previous}}
{{#next}} {{#next}}
<a href="{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <a href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i> <i class="fa fa-angle-right"></i>
</a> </a>
{{/next}} {{/next}}
@@ -225,29 +219,26 @@
{{/if}} {{/if}}
{{#if playpen_js}} {{#if playpen_js}}
<script src="ace.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
<script src="editor.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
<script src="mode-rust.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
<script src="theme-dawn.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
<script src="theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
{{/if}} {{/if}}
{{#if search_enabled}}
<script src="searchindex.js" type="text/javascript" charset="utf-8"></script>
{{/if}}
{{#if search_js}} {{#if search_js}}
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
{{/if}} {{/if}}
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script> <script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts --> <!-- Custom JS scripts -->
{{#each additional_js}} {{#each additional_js}}
<script type="text/javascript" src="{{this}}"></script> <script type="text/javascript" src="{{ path_to_root }}{{this}}"></script>
{{/each}} {{/each}}
{{#if is_print}} {{#if is_print}}