87: Have mdBook not wrap code snippets in "fn main() {}" r=therealprof a=adamgreen

This is the same change as in commit c5caa3b but for the instances I noticed in the rest of the chapters.

Before this change, clicking on the icon to copy a code snippet to the clipboard would result in something like:
```rust
fn main() {
// Exception handler for the SysTick (System Timer) exception
fn SysTick() {
    // ..
}
}
```
After this change, the following would be copied to the clipboard instead:
```rust
// Exception handler for the SysTick (System Timer) exception
fn SysTick() {
    // ..
}
```

Co-authored-by: Adam Green <adamgreen@users.noreply.github.com>
This commit is contained in:
bors[bot]
2018-11-20 08:32:53 +00:00
10 changed files with 32 additions and 32 deletions

View File

@@ -27,7 +27,7 @@ The `alloc` crate is shipped with the standard Rust distribution. To import the
crate you can directly `use` it *without* declaring it as a dependency in your
`Cargo.toml` file.
``` rust
``` rust,ignore
#![feature(alloc)]
extern crate alloc;
@@ -46,7 +46,7 @@ implement a simple bump pointer allocator and use that as the global allocator.
However, we *strongly* suggest you use a battle tested allocator from crates.io
in your program instead of this allocator.
``` rust
``` rust,ignore
// Bump pointer allocator implementation
extern crate cortex_m;
@@ -103,7 +103,7 @@ Apart from selecting a global allocator the user will also have to define how
Out Of Memory (OOM) errors are handled using the *unstable*
`alloc_error_handler` attribute.
``` rust
``` rust,ignore
#![feature(alloc_error_handler)]
use cortex_m::asm;

View File

@@ -473,7 +473,7 @@ fn timer() {
That's quite a lot to take in, so let's break down the important lines.
```rust
```rust,ignore
static MY_GPIO: Mutex<RefCell<Option<stm32f405::GPIOA>>> =
Mutex::new(RefCell::new(None));
```
@@ -487,7 +487,7 @@ to something empty, and only later actually move the variable in. We cannot
access the peripheral singleton statically, only at runtime, so this is
required.
```rust
```rust,ignore
interrupt::free(|cs| MY_GPIO.borrow(cs).replace(Some(dp.GPIOA)));
```
@@ -495,7 +495,7 @@ Inside a critical section we can call `borrow()` on the mutex, which gives us
a reference to the `RefCell`. We then call `replace()` to move our new value
into the `RefCell`.
```rust
```rust,ignore
interrupt::free(|cs| {
let gpioa = MY_GPIO.borrow(cs).borrow();
gpioa.as_ref().unwrap().odr.modify(|_, w| w.odr1().set_bit());

View File

@@ -29,7 +29,7 @@ void cool_function(int i, char c, CoolStruct* cs);
When translated to Rust, this interface would look as such:
```rust
```rust,ignore
/* File: cool_bindings.rs */
#[repr(C)]
pub struct CoolStruct {
@@ -46,27 +46,27 @@ pub extern "C" fn cool_function(
Let's take a look at this definition one piece at a time, to explain each of the parts.
```rust
```rust,ignore
#[repr(C)]
pub struct CoolStruct { ... }
```
By default, Rust does not guarantee order, padding, or the size of data included in a `struct`. In order to guarantee compatibility with C code, we include the `#[repr(C)]` attribute, which instructs the Rust compiler to always use the same rules C does for organizing data within a struct.
```rust
```rust,ignore
pub x: cty::c_int,
pub y: cty::c_int,
```
Due to the flexibility of how C or C++ defines an `int` or `char`, it is recommended to use primitive data types defined in `cty`, which will map types from C to types in Rust
```rust
```rust,ignore
pub extern "C" fn cool_function( ... );
```
This statement defines the signature of a function that uses the C ABI, called `cool_function`. By defining the signature without defining the body of the function, the definition of this function will need to be provided elsewhere, or linked into the final library or binary from a static library.
```rust
```rust,ignore
i: cty::c_int,
c: cty::c_char,
cs: *mut CoolStruct

View File

@@ -34,7 +34,7 @@ most of the `std::os::raw` types in the [`cty`] crate.
As mentioned above, primitive types can be converted
by the compiler implicitly.
```rust
```rust,ignore
unsafe fn foo(num: u32) {
let c_num: c_uint = num;
let r_num: u32 = c_num;

View File

@@ -51,7 +51,7 @@ documented [here](https://doc.rust-lang.org/reference/items/external-blocks.html
Putting these parts together, you get a function that looks roughly like this.
```rust
```rust,ignore
#[no_mangle]
pub extern "C" fn rust_function() {
@@ -77,7 +77,7 @@ the function signatures.
Every function in your Rust-ffi API needs to have a corresponding header function.
```rust
```rust,ignore
#[no_mangle]
pub extern "C" fn rust_function() {}
```

View File

@@ -17,7 +17,7 @@ Let's look at the 'SysTick' peripheral - a simple timer which comes with every C
In Rust, we can represent a collection of registers in exactly the same way as we do in C - with a `struct`.
```rust
```rust,ignore
#[repr(C)]
struct SysTick {
pub csr: u32,
@@ -29,7 +29,7 @@ struct SysTick {
The qualifier `#[repr(C)]` tells the Rust compiler to lay this structure out like a C compiler would. That's very important, as Rust allows structure fields to be re-ordered, while C does not. You can imagine the debugging we'd have to do if these fields were silently re-arranged by the compiler! With this qualifier in place, we have our four 32-bit fields which correspond to the table above. But of course, this `struct` is of no use by itself - we need a variable.
```rust
```rust,ignore
let systick = 0xE000_E010 as *mut SysTick;
let time = unsafe { (*systick).cvr };
```
@@ -46,7 +46,7 @@ Now, there are a couple of problems with the approach above.
Now, the problem is that compilers are clever. If you make two writes to the same piece of RAM, one after the other, the compiler can notice this and just skip the first write entirely. In C, we can mark variables as `volatile` to ensure that every read or write occurs as intended. In Rust, we instead mark the *accesses* as volatile, not the variable.
```rust
```rust,ignore
let systick = unsafe { &mut *(0xE000_E010 as *mut SysTick) };
let time = unsafe { std::ptr::read_volatile(&mut systick.cvr) };
```
@@ -55,7 +55,7 @@ So, we've fixed one of our four problems, but now we have even more `unsafe` cod
[`volatile_register`]: https://crates.io/crates/volatile_register
```rust
```rust,ignore
use volatile_register::{RW, RO};
#[repr(C)]
@@ -84,7 +84,7 @@ We need to wrap this `struct` up into a higher-layer API that is safe for our us
One example might be:
```rust
```rust,ignore
use volatile_register::{RW, RO};
pub struct SystemTimer {
@@ -124,7 +124,7 @@ pub fn example_usage() -> String {
Now, the problem with this approach is that the following code is perfectly acceptable to the compiler:
```rust
```rust,ignore
fn thread1() {
let mut st = SystemTimer::new();
st.set_reload(2000);

View File

@@ -27,7 +27,7 @@ But this has a few problems. It is a mutable global variable, and in Rust, these
Instead of just making our peripheral a global variable, we might instead decide to make a global variable, in this case called `PERIPHERALS`, which contains an `Option<T>` for each of our peripherals.
```rust
```rust,ignore
struct Peripherals {
serial: Option<SerialPort>,
}
@@ -75,7 +75,7 @@ fn main() {
Additionally, if you use `cortex-m-rtfm`, the entire process of defining and obtaining these peripherals are abstracted for you, and you are instead handed a `Peripherals` structure that contains a non-`Option<T>` version of all of the items you define.
```rust
```rust,ignore
// cortex-m-rtfm v0.3.x
app! {
resources: {
@@ -95,7 +95,7 @@ fn init(p: init::Peripherals) -> init::LateResources {
But how do these Singletons make a noticeable difference in how our Rust code works?
```rust
```rust,ignore
impl SerialPort {
const SER_PORT_SPEED_REG: *mut u32 = 0x4000_1000 as _;
@@ -134,7 +134,7 @@ Additionally, because some references are mutable, and some are immutable, it be
This is allowed to change hardware settings:
```rust
```rust,ignore
fn setup_spi_port(
spi: &mut SpiPort,
cs_pin: &mut GpioPin
@@ -145,7 +145,7 @@ fn setup_spi_port(
This isn't:
```rust
```rust,ignore
fn read_button(gpio: &GpioPin) -> bool {
// ...
}

View File

@@ -18,7 +18,7 @@ In our last chapter, we wrote an interface that *didn't* enforce design contract
If we instead checked the state before making use of the underlying hardware, enforcing our design contracts at runtime, we might write code that looks like this instead:
```rust
```rust,ignore
/// GPIO interface
struct GpioConfig {
/// GPIO Configuration structure generated by svd2rust
@@ -103,7 +103,7 @@ Because we need to enforce the restrictions on the hardware, we end up doing a l
But what if instead, we used Rust's type system to enforce the state transition rules? Take this example:
```rust
```rust,ignore
/// GPIO interface
struct GpioConfig<ENABLED, DIRECTION, MODE> {
/// GPIO Configuration structure generated by svd2rust
@@ -211,7 +211,7 @@ impl<IN_MODE> GpioConfig<Enabled, Input, IN_MODE> {
Now let's see what the code using this would look like:
```rust
```rust,ignore
/*
* Example 1: Unconfigured to High-Z input
*/

View File

@@ -53,7 +53,7 @@ Typically the states listed above are set by writing values to given registers m
We could simple expose the following structure in Rust to control this GPIO:
```rust
```rust,ignore
/// GPIO interface
struct GpioConfig {
/// GPIO Configuration structure generated by svd2rust

View File

@@ -2,7 +2,7 @@
Type states are also an excellent example of Zero Cost Abstractions - the ability to move certain behaviors to compile time execution or analysis. These type states contain no actual data, and are instead used as markers. Since they contain no data, they have no actual representation in memory at runtime:
```rust
```rust,ignore
use core::mem::size_of;
let _ = size_of::<Enabled>(); // == 0
@@ -13,7 +13,7 @@ let _ = size_of::<GpioConfig<Enabled, Input, PulledHigh>>(); // == 0
## Zero Sized Types
```rust
```rust,ignore
struct Enabled;
```
@@ -21,7 +21,7 @@ Structures defined like this are called Zero Sized Types, as they contain no act
In this snippet of code:
```rust
```rust,ignore
pub fn into_input_high_z(self) -> GpioConfig<Enabled, Input, HighZ> {
self.periph.modify(|_r, w| w.input_mode().high_z());
GpioConfig {