EmbeddedRelated.com

Flash Memory

Category: Memory | Also known as: flash

Flash memory is a type of non-volatile, electrically erasable, solid-state storage that retains its contents without power. In embedded systems, it is commonly used to hold program code, bootloaders, and persistent configuration or data.

In practice

On most microcontrollers, flash is the primary storage for firmware. The CPU typically executes code directly from internal flash (a technique called XIP, execute-in-place), though some higher-performance SoCs copy code to RAM first to avoid flash access latency. Internal flash densities on MCU-class parts commonly range from a few kilobytes on small 8-bit devices (e.g., PIC10, ATtiny) up to several megabytes on Cortex-M4/M7 parts such as the STM32H7 or SAM E70. External flash chips (SPI NOR, QSPI NOR, parallel NOR, NAND) extend storage capacity when the internal flash is insufficient for assets, filesystems, or firmware update slots.

Flash memory has two key constraints that distinguish it from RAM, though other differences (erase granularity, programming rules, access latency, and controller-specific behavior) also matter in practice. First, writes can only change bits from 1 to 0; restoring bits to 1 requires an erase operation on an entire sector or block, which on most NOR flash parts ranges from 4 KB to 64 KB. Second, flash cells wear out: NOR flash typically endures 10,000 to 100,000 erase/write cycles per sector before reliability degrades, and NAND flash endurance varies widely by type and generation and is often lower, particularly for TLC or QLC devices. Designs that write frequently (e.g., data logging) need wear-leveling strategies or should consider EEPROM or FRAM for small, frequently updated values.

Erasing and writing flash is usually slow relative to RAM access. A sector erase on internal STM32 flash can take tens of milliseconds, and a full-chip erase can take seconds. On many Cortex-M parts, the CPU stalls or must run from RAM during a write to the same flash bank, though exact behavior varies by vendor, flash controller design, and cache configuration. Dual-bank flash controllers (found on parts like the STM32L5, STM32H7, and some nRF53 series devices) generally allow one bank to be erased or programmed while the other is executing, enabling live firmware updates without halting the CPU, though specific restrictions may still apply depending on the controller and operation type.

Firmware update (DFU/OTA) workflows depend heavily on how flash is partitioned. A typical scheme reserves one or more image slots, a bootloader region, and a settings or scratch area. Getting this layout right is critical: a failed write to the wrong address can brick a device in the field. Projects using Zephyr and the MCUboot bootloader define these regions in a partition table; the blog post "nRF5 to nRF Connect SDK migration via DFU over BLE" covers a practical example of managing flash layout during an SDK migration.

Discussed on EmbeddedRelated

Frequently asked

Can I write to flash at any time, or are there restrictions?
On many MCUs, writing to the same flash bank the CPU is executing from will stall the core or cause a fault. Some devices require the write routine itself to run from RAM. Dual-bank controllers avoid this by letting the CPU run from one bank while the other is being programmed. Always check the reference manual for your specific part.
Why can't I just overwrite a byte in flash the way I would in RAM?
Flash cells can only be programmed from 1 to 0 at the bit level. To set any bit back to 1, the entire containing sector must be erased first. This means updating even a single byte typically requires reading the sector into RAM, erasing the sector, modifying the data in the RAM buffer, and writing the entire sector back.
What is the difference between NOR flash and NAND flash in an embedded context?
NOR flash supports random, byte-addressable reads and is suitable for XIP (execute-in-place), making it the standard choice for code storage on MCUs. NAND flash offers higher density and lower cost per bit but requires block-level access, is not directly executable, and typically needs a flash translation layer or filesystem (such as YAFFS or LittleFS) to manage bad blocks and wear. NAND is more common in Linux-class systems needing large storage, not in typical bare-metal MCU designs.
How do I handle the limited erase cycle endurance for data I write frequently?
Common strategies include: using a dedicated EEPROM or FRAM peripheral for frequently updated values; spreading writes across multiple sectors with a simple wear-leveling scheme; or using a filesystem designed for flash (such as LittleFS) that handles wear-leveling and power-safe writes automatically. Zephyr's file system support, discussed in 'Getting Started With Zephyr: Saving Data To Files', is one practical option.
How much flash do I need for a basic firmware project?
This depends heavily on the application, but a minimal bare-metal 'Hello World' on an ARM Cortex-M (toggling an LED and sending a UART string) can fit in 2 to 8 KB of flash. Adding an RTOS, USB stack, or network stack typically pushes requirements into the tens to hundreds of kilobytes. Parts like the STM32F0 start at 16 KB; flagship parts like the STM32H7 offer up to 2 MB internal flash. The blog post 'Introduction to Microcontrollers - Hello World' is a good starting point for understanding the basics.

Differentiators vs similar concepts

Flash is sometimes conflated with EEPROM. Both are non-volatile and electrically erasable, but traditional EEPROM supports byte-level erase and rewrite (with endurance often rated at 1,000,000 cycles or more on many devices, though actual limits vary by process and vendor) at the cost of higher silicon area per bit, making it practical only for small amounts of data. Flash trades finer erase granularity for much higher density and lower cost, which is why it dominates code storage. Many MCUs integrate a small hardware EEPROM peripheral or emulate EEPROM in flash for configuration data. Flash is also distinct from RAM (SRAM, DRAM): RAM is volatile, byte-writable without erase, and far faster for reads and writes, but loses its contents when power is removed.