Overview of Bootloaders and STM32 Flash Memory
Firmware in STM32 microcontrollers is stored in non-volatile flash memory, which retains data even when power is removed. To simplify firmware updates, STM32 devices often use a bootloader, a small program stored in a dedicated flash section that runs during startup.
The bootloader checks for new firmware and loads it into the application memory area when available. This enables firmware updates through interfaces like USB, UART, or SPI without requiring direct access to a debugger or programmer.

STM32 Flash Memory Architecture Explained
Flash memory in STM32 devices is organized into sectors (or pages, depending on the device family), each of which must be fully erased before new data can be written. This is not a detail you can skip, it is a hardware constraint. Flash cells can only transition from a logic 1 to a logic 0 during a write. Erasing restores all bits to 1, making a sector ready for fresh programming.
Key characteristics that define STM32 flash behavior:
- Flash Memory Size: Ranges from around 64 KB on entry-level STM32F0 devices to several megabytes on the STM32H7 and STM32MP series.
- Sector Size: Varies from 1 KB pages (F0, L4) to 16–128 KB sectors (F4, H7). This directly affects how granular your erase operations can be.
- Write/Erase Cycles: Most STM32 families are rated for 10,000 cycles per sector. High-endurance devices and certain STM32H7 configurations support up to 100,000 cycles.
- Memory Layout: The STM32 bootloader typically sits at the start of flash at address 0x08000000, or in dedicated system memory. User application code generally begins at 0x08008000 or a higher address, depending on how much space the bootloader occupies.
The STM32 flash programming manual for each device family (ST reference documents in the PM0xxx series) defines these boundaries precisely. Always consult the manual for your specific device before finalizing your memory map.
STM32 Flash Memory Comparison by Series
STM32 Series | Typical Flash Size | Sector/Page Size | Write/Erase Cycles | Common Update Interfaces |
STM32F0 | 16 KB – 256 KB | 1 KB pages | ~10,000 | UART, SPI |
STM32F4 | 512 KB – 2 MB | 16 – 128 KB sectors | ~10,000 | USB DFU, UART |
STM32L4 | 256 KB – 1 MB | 2 KB pages | ~10,000 | UART, USB |
STM32H7 | Up to 2 MB | 128 KB sectors | Up to 100,000 | USB DFU, Ethernet |
Knowing your target series before starting STM32 flash programming saves significant debugging time and prevents costly architectural mistakes later.
STM32 Bootloader Implementation
What the Bootloader Actually Does
The bootloader’s job is straightforward in principle, but the details matter significantly. A well-designed STM32 bootloader handles the following responsibilities:
- Hardware Initialization: Sets up clocks, USB or UART peripherals, and any GPIOs needed for update trigger detection.
- Update Detection: Checks whether a firmware update has been requested, typically by reading a GPIO pin state, checking a flag stored in flash, or waiting for a trigger byte over UART or USB.
- Firmware Reception: Receives the new binary image over the selected communication interface.
- Flash Erase: Erases the target flash sectors where the new firmware will be written.
- Flash Write: Programs the received image into those sectors.
- Integrity Verification: Computes a CRC32 or checksum over the written data and compares it against a reference value provided with the image.
- Jump to Application: Adjusts the vector table offset register (VTOR), sets the stack pointer, and transfers execution to the application entry point.
Typical STM32 Memory Layout
The standard layout used in most STM32 bootloader projects looks like this:
- Bootloader region: Starts at 0x08000000. Typically occupies 8–32 KB depending on complexity.
- Application region: Starts at 0x08008000 or higher. Contains the user firmware image.
- Configuration/parameter region (optional): Located at a high-address sector. Stores persistent settings that survive firmware updates.
Defining this layout explicitly, before writing a single line of code, prevents the most common class of STM32 flash programming errors.
STM32 Flash Memory Programming: Erase and Write Operations
Flash Sector Erasing
Before writing any new data, the target flash sector must be erased. This is a hardware requirement, not a software choice. STM32 provides hardware-controlled erase operations that set all bits in a sector to 1, making it ready for new data.
When using the STM32 HAL library, flash erase operations use a dedicated FLASH_EraseInitTypeDef structure that specifies whether you are erasing by sector (F4, H7) or by page (F0, L4), along with the start address and count.
Writing Data to Flash: STM32 Flash Write Example
After erasing, data is written in fixed-width increments, 32-bit words on most F-series devices, 64-bit double words on H7. The sequence below represents the standard STM32 flash write example pattern used across HAL-based projects:
- Call HAL_FLASH_Unlock() to allow write operations (flash is locked by default to prevent accidental modification).
- Populate an erase configuration structure specifying the target sector or page range.
- Call HAL_FLASHEx_Erase() to clear the target region.
- Write data using HAL_FLASH_Program(), incrementing the address by the write granularity (4 or 8 bytes) on each iteration.
- Call HAL_FLASH_Lock() immediately after all writes are complete.
- Read back written data and compare it byte-for-byte against the source buffer to verify the operation succeeded.
Never skip step 5. Leaving flash unlocked after programming is a common security oversight that can allow accidental or malicious writes.

Developing a Firmware Update Bootloader
Communication Interfaces for Firmware Updates
The STM32 platform supports several communication interfaces for delivering firmware images. The right choice depends on your application context:
- UART: The most commonly used interface for development and low-volume deployment. Simple to implement, widely supported, and reliable over short distances. The bootloader watches for a trigger command, a specific byte sequence, and then receives the binary in chunks.
- USB DFU (Device Firmware Upgrade): The preferred method for consumer and prosumer devices. USB DFU is supported natively by host tools including dfu-util and STM32CubeProgrammer, making it straightforward to integrate into both manufacturing workflows and end-user update tools.
- SPI: Useful for multi-chip architectures where one microcontroller needs to update another, or when communicating with an external flash chip acting as a staging buffer.
- CAN Bus: Increasingly common in automotive and industrial applications, where firmware updates need to propagate across a network of nodes without physical access to each one.
UART Firmware Update
UART-based firmware updates are widely used in STM32 devices, especially when USB connectivity is unavailable. At startup, the bootloader monitors the UART interface for an update command within a short timeout period.
If an update request is detected, the bootloader receives the firmware image, writes it to flash memory, verifies its integrity, and then launches the new application. If no update command is received, it simply boots the existing firmware without delay.
Common Mistakes in STM32 Flash Programming
Writing Without Erasing First – Flash memory must be erased before writing new data, otherwise firmware corruption can occur.
Using Misaligned Write Addresses – STM32 flash writes require proper memory alignment; incorrect addresses can trigger hard faults.
Skipping CRC Verification – Always verify firmware integrity after programming to detect transmission or storage errors.
Not Protecting the Bootloader – Enable flash protection to prevent accidental or malicious overwriting of the bootloader region.
Best Practices for Production-Ready STM32 Flash Systems
- Plan your memory map early – Clearly define bootloader, application, and data storage regions before development begins.
- Use dual-bank flash when available – Devices like STM32H7, STM32G4, and STM32L4+ support safer firmware updates with minimal downtime.
- Implement a rollback mechanism – Allow the system to revert to a known-good firmware version if an update fails.
- Secure firmware with digital signatures – Verify firmware authenticity using cryptographic signatures to prevent unauthorized updates.
- Test with corrupted firmware images – Validate your bootloader by testing incomplete, damaged, or invalid firmware files to ensure reliable error handling.
STM32 Flash Programming Trends for 2026 and Beyond
Secure Boot Adoption – Hardware-enforced secure boot and TrustZone-enabled STM32 devices are becoming standard for secure embedded applications.
Large-Scale OTA Updates – Cloud-based firmware updates through platforms like AWS IoT and Azure IoT Hub are increasing the need for reliable bootloaders and rollback mechanisms.
Delta Firmware Updates – Instead of sending full firmware images, only changed portions are transmitted, reducing bandwidth usage and speeding up updates for IoT devices.

Conclusion
STM32 flash programming is a fundamental skill for building reliable embedded systems. Understanding flash memory organization, erase/write operations, and bootloader workflows helps ensure safe firmware updates and long-term device stability in real-world deployments.
Whether you’re implementing a UART bootloader or designing a secure update mechanism, the key principles remain the same: plan your memory layout carefully, protect critical bootloader code, verify every firmware write, and always account for update failures. With the tools provided by STM32, a well-designed flash programming strategy can greatly improve the reliability and maintainability of your products.