🛠 Rust embarqué et OpenOCD sur la Discovery F4 : chaîne complète sans CubeIDE
Objective
Develop on Rust for the STM32F4DISCOVERY without any proprietary ST tools: the community HAL stm32f4xx-hal (stm32-rs, active in 2026 for the entire F4 family) + OpenOCD, which provides a ready-to-use board file stm32f4discovery.cfg (ST-LINK interface, SWD, srst_only, 64 KiB work area). This tutorial also documents the actual memory map of the F407VGT6, which "blinky" tutorials often gloss over.
The memory map before coding
- Flash: 1024 KiB starting at
0x0800_0000(the F407VGT6 is the 1 MB version of the range). - SRAM: 192 KiB including 64 KiB of Core-Coupled Memory (CCM) — visible at
0x1000_0000, fast but inaccessible to most DMA controllers: DMA buffers must go in the main 128 KiB SRAM. - +4 KiB of battery-backed RAM (RTC registers and data preserved during power-off).
- SWD debugging via the ST-LINK/V2-A is the standard path: there is no mainstream DFU flow on this board; the system bootloader (USART/DFU via OTG) exists, but the OTG port is separate from the ST-LINK port.
Toolchain
# 1. Toolchain Rust bare-metal
rustup target add thumbv7em-none-eabihf # M4F avec FPU materiel
# 2. OpenOCD voit la carte sans configuration maison :
openocd -f interface/stlink.cfg -f board/stm32f4discovery.cfg
# (le fichier board embarque deja SWD + srst_only + workarea 64K)
# 3. Projet cargo avec stm32f4xx-hal (feature stm32f407, vgt = 1 Mo flash)
cargo build --release --target thumbv7em-none-eabihf
arm-none-eabi-gdb target/thumbv7em-none-eabihf/release/app \
-ex "target remote :3333" -ex load
Code (stm32f4xx-hal)
// LED verte LD4 = PD12, orange LD3 = PD13 — broches verifiees BSP ST
use stm32f4xx_hal::{pac, prelude::*};
fn main -> ! {
let dp = pac::Stm32::take.unwrap;
let cp = cp_core::Peripherals::take.unwrap;
let mut rcc = dp.RCC.constrain;
let mut flash = dp.FLASH.constrain;
// HSE 8 MHz (quartz de la carte) -> 168 MHz systeme
let clocks = rcc.cfgr.use_hse(8.MHz)
.sysclk(168.MHz).freeze(&mut flash.acr);
let mut gpiod = dp.GPIOD.split(&mut rcc.ahb1);
let mut green = gpiod.pd12.into_push_pull_output(&mut gpiod.moder,
&mut gpiod.afr);
let mut delay = cp.SYST.delay(&rcc.clocks);
loop {
green.toggle(&mut gpiod.odr);
delay.delay(1.secs);
}
}
Why OpenOCD instead of CubeProgrammer?
Both work (Zephyr uses CubeProgrammer by default, with --runner openocd as an alternative). OpenOCD offers: open GDB scripts, reset_config srst_only compliant with the board design, and the same demo for CI integration. The tcl/board/stm32f4discovery.cfg file in the OpenOCD repository is the configuration reference.
Expected verification
Open On-Chip Debugger displays Target chip is STM32F4xx; the GDB load command writes to 0x08000000 and the green LED pulses at 1 Hz. In case the board is "stuck" in low power, srst_only ensures that it is the board's physical reset that acts, not a software reset from the ST-LINK.
Common errors
- Placing a DMA buffer in CCM (
0x10000000): the F407 DMA controllers do not see Core-Coupled Memory — keep audio/SPI buffers in the main SRAM. - Compiling for
thumbv7em-none-eabi(withouthf): you lose the M4F hardware FPU, which is critical for DSP/audio. - Forgetting USB permissions (udev) for the ST-LINK on Linux before blaming OpenOCD.
- Following an old online mbed tutorial: the mbed platform was shut down in July 2026; if you want mbed, use the community fork mbed-ce, otherwise stick to this Rust/OpenOCD chain or CubeF4.
Other tutorials for this board
- Premier téléversement sur la STM32F4DISCOVERY avec l'Arduino STM32duino
- Zephyr RTOS sur la STM32F4DISCOVERY : west build et west flash
- MicroPython sur la STM32F4DISCOVERY : REPL interactif et pilotage des LED
- STM32Cube HAL et BSP officiel : LED, bouton et accéléromètre avec détection automatique
- Lecture audio sur le codec CS43L22 : I2S, classe D et les limitations du BSP
- USB OTG FS sur le port micro-AB : se faire passer pour un périphérique classe CDC