mirror of
https://github.com/nkbai/book.git
synced 2026-09-01 12:17:53 +08:00
Merge #180
180: Fix test errors. r=korken89 a=ehuss Upstream rust-lang/rust requires `mdbook test` to pass. See https://github.com/rust-lang/rust/pull/59366#issuecomment-475965444 Co-authored-by: Eric Huss <eric@huss.org>
This commit is contained in:
@@ -2,6 +2,7 @@ set -euxo pipefail
|
||||
|
||||
main() {
|
||||
mdbook build
|
||||
mdbook test
|
||||
|
||||
# FIXME(rust-lang-nursery/mdbook#789) remove `--ignore-url` when that bug is fixed
|
||||
linkchecker --ignore-url "print.html" book
|
||||
|
||||
@@ -79,7 +79,7 @@ for example:
|
||||
const fn array_size() -> usize {
|
||||
#[cfg(feature="use_more_ram")]
|
||||
{ 1024 }
|
||||
#[cfg(not(feature="use_more_ram")]
|
||||
#[cfg(not(feature="use_more_ram"))]
|
||||
{ 128 }
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ happily index outside the array.
|
||||
|
||||
Instead, use iterators:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
let arr = [0u16; 16];
|
||||
for element in arr.iter() {
|
||||
process(*element);
|
||||
@@ -259,7 +259,7 @@ void driver() {
|
||||
|
||||
The equivalent in Rust would use volatile methods on each access:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
static mut SIGNALLED: bool = false;
|
||||
|
||||
#[interrupt]
|
||||
|
||||
@@ -118,7 +118,7 @@ fn on_oom(_layout: Layout) -> ! {
|
||||
|
||||
Once all that is in place, the user can finally use the collections in `alloc`.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut xs = Vec::new();
|
||||
@@ -140,7 +140,7 @@ as they are exact same implementation.
|
||||
`heapless` requires no setup as its collections don't depend on a global memory
|
||||
allocator. Just `use` its collections and proceed to instantiate them:
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
extern crate heapless; // v0.4.x
|
||||
|
||||
use heapless::Vec;
|
||||
|
||||
@@ -22,7 +22,7 @@ are no interrupts at all. Sometimes this is perfectly suited to the problem
|
||||
at hand! Typically your loop will read some inputs, perform some processing,
|
||||
and write some outputs.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
#[entry]
|
||||
fn main() {
|
||||
let peripherals = setup_peripherals();
|
||||
@@ -58,7 +58,7 @@ For an example of how this behaviour can cause subtle errors in your code,
|
||||
consider an embedded program which counts rising edges of some input signal
|
||||
in each one-second period (a frequency counter):
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
static mut COUNTER: u32 = 0;
|
||||
|
||||
#[entry]
|
||||
@@ -99,7 +99,7 @@ sections_, a context where interrupts are disabled. By wrapping the access to
|
||||
`COUNTER` in `main` in a critical section, we can be sure the timer interrupt
|
||||
will not fire until we're finished incrementing `COUNTER`:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
static mut COUNTER: u32 = 0;
|
||||
|
||||
#[entry]
|
||||
@@ -160,7 +160,7 @@ of the time, but if it was interrupted it will automatically retry the entire
|
||||
increment operation. These atomic operations are safe even across multiple
|
||||
cores.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
static COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
@@ -215,7 +215,7 @@ We can abstract our counter into a safe interface which can be safely used
|
||||
anywhere else in our code. For this example we'll use the critical-section
|
||||
counter, but you could do something very similar with atomics.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
use core::cell::UnsafeCell;
|
||||
use cortex_m::interrupt;
|
||||
|
||||
@@ -340,7 +340,7 @@ the lock/unlock state of the mutex.
|
||||
This is in fact done for us in the `cortex_m` crate! We could have written
|
||||
our counter using it:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
use core::cell::Cell;
|
||||
use cortex_m::interrupt::Mutex;
|
||||
|
||||
@@ -410,7 +410,7 @@ the shared variable after it has been initialised in the main code. To do
|
||||
this we can use the `Option` type, initialised to `None` and later set to
|
||||
the instance of the peripheral.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
use core::cell::RefCell;
|
||||
use cortex_m::interrupt::{self, Mutex};
|
||||
use stm32f4::stm32f405;
|
||||
|
||||
@@ -120,7 +120,7 @@ For projects with limited dependencies or complexity, or for projects where it i
|
||||
|
||||
In the simplest case of compiling a single C file as a dependency to a static library, an example `build.rs` script using the [`cc` crate] would look like this:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
extern crate cc;
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
We could make everything a public static, like this
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
static mut THE_SERIAL_PORT: SerialPort = SerialPort;
|
||||
|
||||
fn main() {
|
||||
let _ = unsafe {
|
||||
THE_SERIAL_PORT.read_speed();
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
@@ -44,7 +44,7 @@ static mut PERIPHERALS: Peripherals = Peripherals {
|
||||
|
||||
This structure allows us to obtain a single instance of our peripheral. If we try to call `take_serial()` more than once, our code will panic!
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
let serial_1 = unsafe { PERIPHERALS.take_serial() };
|
||||
// This panics!
|
||||
@@ -60,7 +60,7 @@ This has a small runtime overhead because we must wrap the `SerialPort` structur
|
||||
|
||||
Although we created our own `Peripherals` structure above, it is not necessary to do this for your code. the `cortex_m` crate contains a macro called `singleton!()` that will perform this action for you.
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
#[macro_use(singleton)]
|
||||
extern crate cortex_m;
|
||||
|
||||
@@ -116,7 +116,7 @@ There are two important factors in play here:
|
||||
|
||||
These two factors put together means that it is only possible to access the hardware if we have appropriately satisfied the borrow checker, meaning that at no point do we have multiple mutable references to the same hardware!
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
fn main() {
|
||||
// missing reference to `self`! Won't work.
|
||||
// SerialPort::read_speed();
|
||||
|
||||
@@ -57,7 +57,7 @@ times it has been called in the `COUNT` variable and then prints the value of
|
||||
> **NOTE**: You can run this example on any Cortex-M device; you can also run it
|
||||
> on QEMU
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![deny(unsafe_code)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
@@ -185,7 +185,7 @@ memory location.
|
||||
> `qemu-system-arm -machine lm3s6965evb` doesn't check memory loads and will
|
||||
> happily return `0 `on reads to invalid memory.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ MEMORY
|
||||
Make sure the `debug::exit()` call is commented out or removed, it is used
|
||||
only for running in QEMU.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
hprintln!("Hello, world!").unwrap();
|
||||
|
||||
@@ -69,7 +69,7 @@ with the release profile (`cargo build --release`).
|
||||
Here's an example that tries to index an array beyond its length. The operation
|
||||
results in a panic.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ substitutions.
|
||||
|
||||
For convenience here are the most important parts of the source code in `src/main.rs`:
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
@@ -300,7 +300,7 @@ Next, let's see how to run an embedded program on QEMU! This time we'll use the
|
||||
|
||||
For convenience here's the source code of `examples/hello.rs`:
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
//! Prints "Hello, world!" on the host console using semihosting
|
||||
|
||||
#![no_main]
|
||||
|
||||
@@ -21,7 +21,7 @@ You may well find that the code you need to access the peripherals in your micro
|
||||
|
||||
Let's look at the SysTick peripheral that's common to all Cortex-M based micro-controllers. We can find a pretty low-level API in the [cortex-m] crate, and we can use it like this:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
use cortex_m::peripheral::{syst, Peripherals};
|
||||
use cortex_m_rt::entry;
|
||||
|
||||
@@ -125,7 +125,7 @@ The HAL crate for a chip typically works by implementing a custom Trait for the
|
||||
|
||||
Let's see an example:
|
||||
|
||||
```rust
|
||||
```rust,ignore
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ world!":
|
||||
|
||||
[`cortex-m-semihosting`]: https://crates.io/crates/cortex-m-semihosting
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
@@ -63,7 +63,7 @@ QEMU process. Important: do **not** use `debug::exit` on hardware; this function
|
||||
can corrupt your OpenOCD session and you will not be able to debug more programs
|
||||
until you restart it.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
@@ -101,7 +101,7 @@ For convenience, the `panic-semihosting` crate has an "exit" feature that when
|
||||
enabled invokes `exit(EXIT_FAILURE)` after logging the panic message to the host
|
||||
stderr.
|
||||
|
||||
``` rust
|
||||
```rust,ignore
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user