Repository navigation
Port STM32 Firmware
Every release has a complete
firmware for these boards: flash it, open the board's serial port at 115200 baud (or
MicroCS Studio) and you get the C# REPL, the shell and
the Studio upload protocol, with /boot.cs, /main.cs and your files kept in the chip's own
flash. No CubeMX project, no toolchain.
| Board | File | Console | Files (TinyFS) | VM heap |
|---|---|---|---|---|
| Nucleo-F401RE | microcs-<v>-nucleo_f401re.bin |
ST-LINK USB (USART2) | 28 KB | 67 KB |
| Nucleo-F411RE | microcs-<v>-nucleo_f411re.bin |
ST-LINK USB (USART2) | 28 KB | 99 KB |
| Nucleo-F446RE | microcs-<v>-nucleo_f446re.bin |
ST-LINK USB (USART2) | 28 KB | 99 KB |
| Black Pill F411CE (WeAct) | microcs-<v>-blackpill_f411ce.bin |
USART1: PA9 = TX, PA10 = RX (USB-serial adapter, 3.3 V) | 28 KB | 99 KB |
| Nucleo-G474RE | microcs-<v>-nucleo_g474re.bin |
ST-LINK USB (LPUART1) | 105 KB | 99 KB |
| Nucleo-L476RG | microcs-<v>-nucleo_l476rg.bin |
ST-LINK USB (USART2) | 105 KB | 67 KB |
| Nucleo-H743ZI / H743ZI2 | microcs-<v>-nucleo_h743zi.bin |
ST-LINK USB (USART3) | 307 KB | 467 KB |
The F4/G4/L4 builds use the embedded profile (on-device compiler + REPL), the H743 build
everything (auto profile from the chip's memory).
-
Nucleo boards: plug in the ST-LINK USB, copy the
.binto theNOD_xxxdrive that appears; the board restarts with MicroCS. Or use STM32CubeProgrammer (STM32_Programmer_CLI -c port=SWD -w microcs-<v>-<board>.hex -v -rst) — the.hexholds only the program, so your files survive a firmware update; the.bincovers the file area too and starts with an empty filesystem. -
Black Pill: hold BOOT0, tap NRST, release BOOT0 (USB DFU mode), then
dfu-util -a 0 -s 0x08000000:leave -D microcs-<v>-blackpill_f411ce.bin— or an ST-LINK on the SWD pins. Connect a USB-serial adapter to PA9/PA10 for the console. -
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program microcs-<v>-<board>.hex verify reset exit"works for every board (use the matchingtarget/stm32xxx.cfg).
| C# | Nucleo-64 (F401/F411/F446/G474/L476) | Nucleo-H743ZI | Black Pill F411CE |
|---|---|---|---|
new Pin("LED") |
PA5 (LD2) | PB0 (LD1) | PC13 (lights when low) |
any new Pin("PB3") … |
every GPIO, with interrupts | every GPIO | every GPIO |
I2C.Open(1, …) |
PB8 = SCL (D15), PB9 = SDA (D14) | PB8 / PB9 (D15 / D14) | PB6 = SCL, PB7 = SDA |
PWM.Set(0..3, …), Servo(0..3)
|
TIM3: PA6 (D12), PA7 (D11), PB0 (A3), PB1 | TIM3: PA6, PB5, PC8, PC9 | TIM3: PA6, PA7, PB0, PB1 |
UART.Open(n) / console |
2 (G474: 1 = LPUART1) | 3 | 1 |
Watchdog, Hal.Board, Hal.Millis, files, scheduler, ws2812 (bit-banged on any pin) |
✓ | ✓ | ✓ |
The four PWM pins start as timer outputs (low); new Pin(...) on one of them turns it back
into a GPIO. SPI, ADC, DAC, CAN and the other peripherals need their pins and clocks chosen
for your hardware — use the CubeMX route (example_main.c) for those.
Clocks run from the internal HSI oscillator + PLL (no crystal needed): F401 84 MHz, F411 100 MHz, F446 168 MHz, G474 170 MHz, L476 80 MHz, H743 400 MHz.
| Family | Program | Files |
|---|---|---|
| F4 (512 KB) | sector 0 (vector table) + sectors 4–7 | sectors 1–3 (3 × 16 KB, next to the vector table — the big 128 KB sectors are needed for the program) |
| G474 / L476 | from 0x08000000 | top 128 KB (32 blocks of 4 KB = 2 pages, in bank 2 of these dual-bank parts: no CPU stall while erasing) |
| H743 | from 0x08000000 | top 512 KB (4 × 128 KB sectors, bank 2) |
A write that erases a sector stalls the CPU on single-bank F4 parts (≈ 0.3 s for a 16 KB sector); uploads from Studio and the shell retry, so this is harmless.
sh tools/build_stm32_firmware.sh list # the boards
sh tools/build_stm32_firmware.sh nucleo_f446re # -> build/fw/stm32/microcs-nucleo_f446re.{elf,bin,hex}Needs arm-none-eabi-gcc (Arm GNU Toolchain or apt install gcc-arm-none-eabi libnewlib-arm-none-eabi);
the script downloads the STM32Cube HAL + CMSIS of the family once (into build/sdk, or set
STM32_SDK). Board setup: board.c; memory map: stm32.ld.
To add a board, add a line to the table in the script and a block in board.c (console
UART + pins, LED, clock).
CI builds all boards on every push and boots the F4 and H743 images in the
Renode emulator (tools/renode_check.py): REPL prompt, an expression,
Hal.Board, a file written to and read back from the emulated internal flash, the LED pin.
The G474 and L476 images are built and linked but Renode has no model for those chips.
Generated from the MicroCS repository - edit the files there, not in the wiki.
Start here
Step-by-step guides
- Guides
- Guide PC Simulator
- Guide ESP32
- Guide ESP32 C3 OLED
- Guide Raspberry Pi Pico
- Guide STM32
- Guide Arduino
- Guide Zephyr
- Guide Peripheral Settings
- Guide DMA
Hardware
- Hardware API
- Power Management
- Bluetooth LE
- Peripheral Configuration
- DMA
- Device Drivers
- Wi Fi and Networking
- U8g2 Displays
- Filesystem
- Threads
- Scheduler
Ports
- Porting and Build Systems
- Port ESP32
- Port RP2040 RP2350
- Port STM32
- Port STM32 Firmware
- Port Zephyr
- Port Arduino
C# and the runtime
Embedding and tuning
Internals
Project