Files
rust-stm32/README.md
2026-05-25 19:27:51 +02:00

176 lines
4.5 KiB
Markdown

# Rust on STM32
## Hardware Baseline
- Default board: STM32F103C8T6 Blue Pill, Cortex-M3
- Default target: `thumbv7m-none-eabi`
- Default `probe-rs` chip name: `STM32F103C8`
- Default probe: ST-Link v2
- Also supported in docs: Rusty Probe and other `probe-rs` compatible probes
- Onboard LED: usually `PC13`, active-low on most Blue Pill boards
See [blue-pill.md](docs/hardware/blue-pill.md) for wiring notes.
## Attached Hardware
- internal LED: `PC13`
- RGB LED:
- `PA0` = GND, drive low
- `PA1` = red
- `PA2` = green
- `PA3` = blue
- 5-way button board:
- `PB12` = GND, drive low
- `PA10` = VCC, drive high
- `PB13` = right
- `PB14` = down
- `PB15` = left
- `PA8` = center
- `PA9` = up
- HMC5883L module:
- `PB4` = VCC, drive high
- `PB5` = GND, drive low
- `PB6` = SCL
- `PB7` = SDA
- `PB8` = DRDY
## Important Target Note
- Blue Pill `STM32F103` is Cortex-M3 and uses `thumbv7m-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](Cargo.toml) - workspace root and pinned shared dependencies
- [flake.nix](flake.nix) - reproducible development shell
- [.cargo/config.toml](.cargo/config.toml) - default target and linker settings
- [memory.x](memory.x) - conservative Blue Pill memory map
- [justfile](justfile) - build, flash, run, and lint commands
- [examples/README.md](examples/README.md) - example index
## Nix Setup
Use Nix flakes. No global `rustup`. No global `cargo install`.
```bash
nix develop
```
The dev shell provides:
- pinned Rust toolchain
- `cargo`, `rustc`, `rustfmt`, `clippy`
- `rust-src`
- targets for `thumbv7m-none-eabi` and `thumbv6m-none-eabi`
- `probe-rs`
- `flip-link`
- `cargo-binutils`
- `just`
## First Commands
```bash
nix develop
just build
just flash-blinky
just run-blinky
```
If your chip name differs from the default, override it:
```bash
PROBE_RS_CHIP=STM32F103C8 just flash-blinky
```
If you need to inspect available names:
```bash
probe-rs chip list | rg STM32F103
```
## Examples
- `blinky-basic` - plain `no_std` blink with a simple delay
- `blinky-timer` - periodic blink driven by a timer abstraction
- `button-input` - poll the center button on `PA8`, mirror state on the LED, log transitions
- `embassy-blinky` - minimal async blink with Embassy
- `embassy-button` - minimal Embassy polling loop for the center button on `PA8`
- `embassy-rgb-check` - simple RGB on/off check on `PA1`/`PA2`/`PA3`
- `embassy-rgb` - async RGB PWM animation on `PA1`/`PA2`/`PA3`
The button examples assume the 5-way board is wired like this:
- `PB12` forced low for ground
- `PA10` forced high for power
- `PA8` used 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` -> `SWDIO`
- `SWCLK` -> `SWCLK`
- `GND` -> `GND`
- `3V3` -> `3V3` reference
Keep `BOOT0` low for normal flash-and-run.
## Rusty Probe / probe-rs Note
- `probe-rs` is the primary flash, run, and debug path in this repo.
- Rusty Probe works if the host sees it as a `probe-rs` compatible probe.
- Start with `probe-rs list` to 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](memory.x).
## Troubleshooting
### Probe not found
- Run `probe-rs list`.
- Check USB cable and power.
- Check `SWDIO`, `SWCLK`, `GND`, and `3V3`.
### 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-blinky` or `just run-embassy-blinky`.
- Confirm the firmware did not crash early.
- Confirm the probe stays attached.
- Confirm `BOOT0` is low.
### Blue Pill LED looks inverted
- That is expected on most boards.
- `PC13` is usually active-low, so driving it low turns the LED on.
## Safety
- Check board voltage before connecting anything.
- Check `SWDIO`, `SWCLK`, `GND`, and `3V3` wiring 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`, and `just build` working.
- Document hardware assumptions when they matter.
- Do not claim hardware-tested behavior unless it was actually tested on hardware.