What this is
A USART bootloader for STM32G0 (with room for C0 later). One physical UART does every role: multi-drop command bus, application self-update, and programming blank parts on the same wire. The firmware switches USART mode at runtime; it does not add a second UART.
Reference board is the Nucleo-G031K8 (STM32G031K8, 64 KiB flash). Build is PlatformIO with separate bootloader and application images, fixed flash layout, and Python host tools for exercise and flash over the ST-Link VCP.
Why one UART
Field nodes often get a single serial path to the outside world. Carrying a debug probe, a second UART, or a dedicated SWD header for every blank part is fine on the bench and awkward in a multi-drop harness.
The design treats that constraint as a feature: program the loader itself, reload the application, and talk to a factory ROM bootloader on a blank G0 - all on the same TX/RX pair. Normal traffic uses a custom framed protocol at 115200 8N1. On command, the same pins reconfigure for ST ROM framing (AN3155), run erase/write/verify, then return to command mode.
Three roles on the programmed device
Boot. After reset, decide whether to stay in the loader or jump to the application. Stay-in-loader when a backup flag is set, the app image is invalid, or a short magic sequence arrives on the bus during a listen window. Otherwise validate the app vector table and jump.
Reload. In loader mode, the host can erase, write, and verify the application region over the framed protocol - no SWD required for day-to-day app updates. CRC metadata and a failed-boot counter keep a bad image from bricking the node.
Program blanks. On command, the loader becomes a bridge to the target’s factory ROM bootloader on the shared bus. Sync, ID, erase, write, and verify run as AN3155 sequences while peers stay quiet. Then the USART reverts to the multi-drop command profile.
What works today
Boot decision and app jump are hardware-proven on Nucleo. Framed protocol carries ping, info, enter-boot, jump-app, flash erase/write/verify, and commit. Host scripts upload a new application over VCP and exercise the suite after reset. Application soft-entry back into the loader is supported.
Blank-target path is in place on the wire side: bus mode switch, AN3155 subset, and host-side ROM simulation for single-board validation without a second MCU. Multi-drop addressing is designed (broadcast, unicast, discovery/assign); single-node Nucleo work uses a simple default address while that path matures.
Board-specific pin and USART choice live in a profile header, so the protocol and flash code stay shared when a production USART1 board appears later.
What it is not
Not a wireless updater, not an encrypted/signed image pipeline, and not a general multi-family ST bootloader. SWD is for development and bring-up, not the field path. Scope is intentionally G0-first and small-flash-aware - the bootloader reservation is measured and grown only when needed.
Looking ahead
More host polish, wider multi-drop exercise, and additional board or C0 profiles as hardware shows up. The core idea stays the same: one USART, clear modes, and a loader that can both own its own app and seed a blank neighbor.
Bottom line
A small STM32G0 loader built around a single serial wire. Jump when the app is good, stay when it is not, reload without a probe, and - when needed - reconfigure the same UART to speak factory ROM so a blank part on the bus can be brought to life.
references