In Bobbin CLI: Getting to Blinky I introduced Bobbin CLI,
but I didn’t actually answer how you actually get to Blinky, the embedded world’s
“Hello, World”.
There are many excellent posts and tutorials showing how to get a board
blinking using many different different types of hardware and development tools,
including the excellent Rust your ARM microcontroller.
But sometimes you need something more basic: you simply want to know whether
your toolchain and hardware work!
It also may be the case that you have hardware that isn’t covered by an existing project,
particularly if you are using Rust. There are hundreds of development boards out there,
but there are only a small handful that have any kind of Rust projects associated with them.
This is what Bobbin Blinky is: a
collection of minimal Blinky applications.
These crates are meant to be fast to compile and easy to debug. This means:
- Each crate is board specific.
- There are no additional dependencies, not even compiler_builtins.
- Code is generated using
opt-level = "s"
- All peripheral access is using ptr::read_volatile and ptr::write_volatile.
- No clock configuration is performed.
- Hardware watchdogs are disabled if enabled by default.
- The blink rate is approximate.
- Exceptions and panics are handled by infinite loop.
- Constants are hard coded.
An example - the STM32 Nucleo-F429ZI development board:
#![no_std]
#![no_main]
#![feature(asm)]
#![feature(lang_items)]
pub mod lang_items;
pub mod exceptions;
use core::ptr;
// LED0 = PB0;
pub const RCC_AHB1ENR: *mut u32 = 0x4002_3830 as *mut u32;
pub const GPIOB_MODER: *mut u32 = 0x4002_0400 as *mut u32;
pub const GPIOB_BSRR: *mut u32 = 0x4002_0418 as *mut u32;
#[no_mangle]
pub extern "C" fn main() -> ! {
unsafe {
// Enable PORTB
ptr::write_volatile(RCC_AHB1ENR, ptr::read_volatile(RCC_AHB1ENR) | 1 << 1);
// Set PB0 Mode = Output
ptr::write_volatile(GPIOB_MODER, ptr::read_volatile(GPIOB_MODER) | 1 << 0);
loop {
// Set PB0
ptr::write_volatile(GPIOB_BSRR, 1 << 16);
// Delay approx 1/2 second
for _ in 0..2_000_000 { asm!("nop") }
// Reset Set PB0
ptr::write_volatile(GPIOB_BSRR, 1 << 0);
// Delay approx 1/2 second
for _ in 0..2_000_000 { asm!("nop") }
}
}
}
produces a binary of this size in about 1⁄10 second of compile time:
$ bobbin build
Compiling nucleo-f429zi v0.1.0 (file:///home/bobbin/bobbin-blinky/nucleo-f429zi)
Finished dev [optimized + debuginfo] target(s) in 0.12 secs
text data bss dec hex filename
148 0 4 152 98 target/thumbv7em-none-eabihf/debug/nucleo-f429zi
$
which can then be loaded onto a board so that you can see it work:
$ bobbin load
Finished dev [optimized + debuginfo] target(s) in 0.0 secs
text data bss dec hex filename
148 0 4 152 98 target/thumbv7em-none-eabihf/debug/nucleo-f429zi
Loading target/thumbv7em-none-eabihf/debug/nucleo-f429zi
Complete Successfully flashed device
Loader Load Complete
$
These crates don’t replace proper examples and tutorials, but I hope they’re a resource
that both new and experienced developers use when want to do a quick end-to-end check
of their toolchain and their hardware. The ultimate goal is have a crate for every
significant commerial and open source board that it is possible to target using Rust.
Currently, 23 boards covering roughly 20 Cortex-M MCUs from seven different vendors are
represented.
Development Boards with Embedded Debug Probes
Boards without Embedded Debug Probes
Future Boards
Boards that are currently unsupported at this time but of interest:
Feel free contact me with suggestions of other interesting boards to add to the list.
Troubleshooting
If you get errors or the board simply doesn’t blink, here’s a good list of things to check:
- Make sure you have the most recent version of Bobbin CLI by running
cargo install bobbin-cli --force
.
- Run
bobbin check
to see the versions of the prerequisites that Bobbin CLI can find. You may need
to install newer versions of these prerequisites.
- The next most likely cause is the firmware for the on-board debugger if your board has one. You
may wish to review Bobbin CLI - Development Board Firmware for an overview of the situation and links
to updated versions.
Conclusion
It’s incredibly satisfying getting boards up and running from scratch. Go out, grab a board, and make it blink!