Rust on STM32
Hardware Baseline
- Default board: STM32F103C8T6 Blue Pill, Cortex-M3
- Default target:
thumbv7m-none-eabi - Default
probe-rschip name:STM32F103C8 - Default probe: ST-Link v2
- Also supported in docs: Rusty Probe and other
probe-rscompatible probes - Onboard LED: usually
PC13, active-low on most Blue Pill boards
See blue-pill.md for wiring notes.
Attached Hardware
- internal LED:
PC13 - RGB LED:
PA0= GND, drive lowPA1= redPA2= greenPA3= blue
- 5-way button board:
PB12= GND, drive lowPA10= VCC, drive highPB13= rightPB14= downPB15= leftPA8= centerPA9= up
- HMC5883L module:
PB4= VCC, drive highPB5= GND, drive lowPB6= SCLPB7= SDAPB8= DRDY
Important Target Note
- Blue Pill
STM32F103is Cortex-M3 and usesthumbv7m-none-eabi. - STM32F0 is Cortex-M0 and uses
thumbv6m-none-eabi. - Do not mix them.
- This repo leaves room for STM32F0 later, but the default path is STM32F103 only.
Repo Layout
- Cargo.toml - workspace root and pinned shared dependencies
- flake.nix - reproducible development shell
- .cargo/config.toml - default target and linker settings
- memory.x - conservative Blue Pill memory map
- justfile - build, flash, run, and lint commands
- examples/README.md - example index
Nix Setup
Use Nix flakes. No global rustup. No global cargo install.
nix develop
The dev shell provides:
- pinned Rust toolchain
cargo,rustc,rustfmt,clippyrust-src- targets for
thumbv7m-none-eabiandthumbv6m-none-eabi probe-rsflip-linkcargo-binutilsjust
First Commands
nix develop
just build
just flash-blinky
just run-blinky
If your chip name differs from the default, override it:
PROBE_RS_CHIP=STM32F103C8 just flash-blinky
If you need to inspect available names:
probe-rs chip list | rg STM32F103
Examples
blinky-basic- plainno_stdblink with a simple delayblinky-timer- periodic blink driven by a timer abstractionbutton-input- poll the center button onPA8, mirror state on the LED, log transitionsembassy-blinky- minimal async blink with Embassyembassy-button- minimal Embassy polling loop for the center button onPA8embassy-rgb-check- simple RGB on/off check onPA1/PA2/PA3embassy-rgb- async RGB PWM animation onPA1/PA2/PA3
The button examples assume the 5-way board is wired like this:
PB12forced low for groundPA10forced high for powerPA8used as the center button input- internal pull-down enabled in firmware
- common ground still required for the probe
ST-Link Setup
Typical SWD wiring:
SWDIO->SWDIOSWCLK->SWCLKGND->GND3V3->3V3reference
Keep BOOT0 low for normal flash-and-run.
Rusty Probe / probe-rs Note
probe-rsis the primary flash, run, and debug path in this repo.- Rusty Probe works if the host sees it as a
probe-rscompatible probe. - Start with
probe-rs listto confirm the probe is visible.
Memory Note
Many Blue Pill boards have 64K or 128K flash despite markings. This repo uses a conservative 64K flash map in memory.x.
Troubleshooting
Probe not found
- Run
probe-rs list. - Check USB cable and power.
- Check
SWDIO,SWCLK,GND, and3V3.
Linux udev permissions
- You may need udev rules for ST-Link or your probe.
- Install the vendor or distro rules, then replug the probe.
Wrong chip selected
- Run
probe-rs chip list | rg STM32F103. - Override the default with
PROBE_RS_CHIP=....
No RTT or defmt output
- Use
just run-blinkyorjust run-embassy-blinky. - Confirm the firmware did not crash early.
- Confirm the probe stays attached.
- Confirm
BOOT0is low.
Blue Pill LED looks inverted
- That is expected on most boards.
PC13is usually active-low, so driving it low turns the LED on.
Safety
- Check board voltage before connecting anything.
- Check
SWDIO,SWCLK,GND, and3V3wiring before flashing. - Do not assume a random button or LED pinout without checking the board.
Contribution
- Keep examples independent.
- Keep demo reliability first.
- Keep
nix develop,just fmt,just check, andjust buildworking. - Document hardware assumptions when they matter.
- Do not claim hardware-tested behavior unless it was actually tested on hardware.
Description
Languages
Just
61.4%
Nix
33.5%
RPC
5.1%