Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Embedded Setup

Let's take a look at our first program to compile. Check the examples/init.rs file:

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m::asm;
use cortex_m_rt::entry;
use microbit as _;
use panic_halt as _;

#[entry]
fn main() -> ! {
    #[allow(clippy::needless_late_init)]
    let _y;
    let x = 42;
    _y = x;

    // infinite loop; just so we don't leave this stack frame
    loop {
        asm::nop();
    }
}

Microcontroller programs are different from standard programs in two aspects: #![no_std] and #![no_main].

The no_std attribute says that this program won't use the std crate, which assumes an underlying OS; the program will instead use the core crate, a subset of std that can run on bare metal systems (that is, systems without OS abstractions like files and sockets).

The no_main attribute says that this program won't use the standard main interface, which is tailored for command line applications that receive arguments. Instead of the standard main we'll use the entry attribute from the cortex-m-rt crate to define a custom entry point. In this program we have named the entry point main, but any other name could have been used. The entry point function must have signature fn() -> !; this type indicates that the function can't return. This means that the program never terminates by returning from main: if the compiler detects that this would be possible it will refuse to compile your program.

If you are a careful observer, you'll also notice there is a possibly-hidden .cargo directory in the Cargo project as well. This directory contains a Cargo configuration file .cargo/config.toml.

[build]
target = "thumbv7em-none-eabihf"

[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip nRF52833_xxAA"
rustflags = [
  "-C", "linker=rust-lld",
]

This file tweaks the linking process to tailor the memory layout of the program to the requirements of the target device. This modified linking process is a requirement of the cortex-m-rt crate. The .cargo/config.toml file also tells Cargo how to build and run code on our MB2.

There is also an Embed.toml file here:

[default.general]
chip = "nrf52833_xxAA"

[default.reset]
halt_afterwards = true

[default.rtt]
enabled = false

[default.gdb]
enabled = true

This file tells cargo-embed that:

  • We are working with an NRF52833.
  • We want to halt the chip after flashing it, so our program stops before main.
  • We want to disable RTT. RTT is a protocol that allows the chip to send text to a debugger. You have already seen RTT in action: it was the protocol that sent "Hello World" in chapter 3.
  • We want to enable GDB. This will be required for the debugging procedure.

Now that we've seen what's going on, let's start by building this program.