I finally sat down with embedded Rust on a Blue Pill, the cheap STM32F103 board, and got an LED blinking. Which sounds like nothing, and is the "hello world" of microcontrollers, but doing it in Rust felt different enough to be worth a note.
The toolchain is more mature than I expected. cargo cross-compiles to thumbv7m-none-eabi, the stm32f1xx-hal crate gives you a typed peripheral access layer, and probe-run flashes and runs it over an ST-Link as if it were a normal binary. No separate flashing dance, just cargo run.
let mut gpioc = dp.GPIOC.split();
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
loop {
led.set_high();
delay.delay_ms(500u16);
led.set_low();
delay.delay_ms(500u16);
}
The lovely part is that the HAL encodes pin state in the type system. You cannot read from a pin you have configured as a push-pull output, because that method does not exist on that type. The peripheral can only be split once. On a platform where the classic bug is poking the wrong register in the wrong mode, having the compiler refuse the nonsensical thing outright is genuinely reassuring.
It is one LED and 500ms of nothing. But it is a type-checked LED, and the board did exactly what the types said it would. I am quietly delighted, and slightly worried about how much money I am about to spend on more boards.