Embedded flash is non-volatile memory fabricated on the same die as the processor or microcontroller, used to store firmware, constants, and configuration data that must survive power loss. Unlike external flash chips, it is accessed directly over the internal bus and requires no separate chip-select or SPI/QSPI protocol.
In practice
On most general-purpose microcontrollers — STM32, nRF52, LPC, SAM, MSP430, PIC, AVR, and many others — the program itself executes directly from embedded flash (execute-in-place, XIP), though some devices boot from flash but run performance-critical code from RAM. The CPU fetches instructions over the internal bus at whatever width the flash interface supports, typically 32 or 64 bits, often with a prefetch buffer or instruction cache to mitigate the latency gap between flash and the CPU clock. On Cortex-M parts running above a device-dependent frequency threshold (commonly somewhere in the range of tens of MHz), wait states must be configured before increasing the clock, or the CPU will read unreliable or invalid data. This is a common early bringup mistake covered in startup code and discussed in resources like "Boot Sequence for an ARM based embedded system."
Embedded flash is organized into erasable sectors or pages, and the erase granularity varies widely across families. STM32F4 parts use large sectors (16 KB to 128 KB), making fine-grained in-application updates difficult without careful layout. STM32L0/L4 and nRF52 series use much smaller pages (2 KB or 4 KB), which is friendlier for storing configuration or performing over-the-air firmware updates. The "nRF5 to nRF Connect SDK migration via DFU over BLE" post illustrates how flash layout and erase constraints directly shape bootloader and DFU design.
Write and erase operations on embedded flash typically stall the bus, meaning the CPU cannot fetch instructions from flash while a write or erase is in progress — unless the MCU provides a second flash bank (dual-bank operation) or the code executing the write has been copied to RAM first. Failing to account for this can cause hard faults or lockups. Some devices, like the STM32G0/G4 and certain nRF53 parts, offer dual-bank configurations that can allow execution from one bank while the other is being erased or written, though seamless background operation depends on the specific part and configuration.
Endurance is finite: embedded flash is commonly rated for roughly 10,000 to 100,000 erase/write cycles per sector, though the actual rating varies by process node, temperature, voltage, and device family and may fall outside this range. Repeatedly writing to the same sector — for example, storing a frequently updated counter — will eventually wear it out. Wear-leveling schemes, whether implemented manually or via a library like NVS or LittleFS, spread writes across multiple sectors to extend flash lifetime.
Discussed on EmbeddedRelated
Frequently asked
What is the difference between embedded flash and an external flash chip?
Embedded
flash is integrated on the same silicon die as the CPU and is accessible over the internal memory bus, allowing direct code execution (XIP) with no protocol overhead. External flash (
SPI NOR,
QSPI NOR, NAND, etc.) sits on a separate chip connected via a serial or parallel bus. External flash typically offers much larger capacity and is easier to update independently, but adds
latency, power, board space, and often requires copying code to
RAM before execution.
Why does my MCU need wait states configured for flash, and what happens if I get them wrong?
Embedded
flash has an access time measured in nanoseconds that does not scale with the CPU clock. At higher CPU frequencies, the bus cycle is shorter than the flash read time, so wait states hold the bus idle for one or more extra cycles until the data is valid. The required number of wait states is a function of supply voltage and target CPU frequency and is specified in the datasheet. Configuring too few wait states causes the CPU to latch incorrect data, leading to unpredictable behavior, crashes, or corrupted execution. The wait states must be set before raising the clock, not after.
Can I write to embedded flash while my code is running from it?
On most single-bank MCUs, a
flash write or erase operation stalls the instruction bus for its entire duration, so code running from flash is effectively frozen. The standard workaround is to copy the flash-programming routine into
RAM and execute it from there. Some MCUs — for example, dual-bank STM32G4 and STM32H7 parts, and certain nRF53 configurations — allow writes to one bank while the CPU executes from the other, eliminating the need for RAM-resident programming code.
How do I avoid wearing out embedded flash when I need to store frequently changing data like a counter or calibration value?
Write endurance for embedded
flash is typically 10,000 to 100,000 erase/write cycles per sector, depending on the process node and vendor. To extend lifetime, avoid erasing the same sector repeatedly. Common strategies include appending new values sequentially across a reserved region and wrapping around (a simple log), or using a managed filesystem or key-value store such as LittleFS, Zephyr NVS, or emulated
EEPROM drivers that implement
wear leveling automatically.
What is the minimum granularity for erasing embedded flash, and why does it matter for firmware layout?
Erase granularity varies by device and matters because you can only erase entire sectors at once, not individual bytes or words. On some STM32F4 variants, the smallest sector is 16 KB; on some STM32L0 and nRF52 variants it is 2 KB, though the exact size depends on the specific part within each family. If your
bootloader and application share a sector, updating one risks corrupting the other. Careful
linker script design keeps bootloader, application, and data storage in separate, non-overlapping sectors aligned to the erase boundary.
Differentiators vs similar concepts
Embedded
flash is sometimes conflated with
EEPROM. Both are non-
volatile, but EEPROM traditionally allows byte-level erase and write with no bulk-erase requirement, and is rated for higher endurance (often 100,000 to 1,000,000 cycles). Many modern MCUs have dropped dedicated EEPROM and instead emulate it in a reserved flash region using a software
wear-leveling layer. Embedded flash is also distinct from external
NOR flash (e.g., a Winbond W25Q series
SPI chip): the physics are similar, but external NOR flash is a separate component accessed via a serial protocol and cannot be executed in place without an XIP-capable
QSPI controller.