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.