UNIT 03 · LESSON 4 OF 6

Flash, RAM, and Nonvolatile Memory

What is the rule, and how do you store a setting that must survive ten years of power cycles when each piece of flash can only be rewritten a few thousand times?

INTERACTIVEProgramming flash can only clear bits
Bits of a flash byte before and after programming, with bits that cannot be set highlightedflash now07061514131201000x3Cwrite value010110100x5Astored result000110000x180x3C AND 0x5A = 0x18, not 0x5A. Bits 1, 6 needed a 1 but were already 0; only erasingthe sector can restore them.
Bits of a flash byte before and after programming, with bits that cannot be set highlightedflash now07061514131201000x3Cwrite value010110100x5Astored result000110000x180x3C AND 0x5A = 0x18, not 0x5A. Bits 1, 6 needed a 1but were already 0; only erasing the sector canrestore them.

Try this

Operation
0x3C AND 0x5A = 0x18, not 0x5A. Bits 1, 6 needed a 1 but were already 0; only erasing the sector can restore them.

Erased NOR flash reads as all ones (0xFF). Programming a byte can change 1s to 0s but never 0s back to 1s, so the stored result is the old contents AND the new value. The only way back to 1 is to erase a whole sector at once: 4096 bytes on the flash chips the RP2040 SDK supports. Change the old contents and the value you want to write.

What you will be able to do
  • Classify the memories found in a microcontroller (SRAM, NOR flash, EEPROM, ROM, OTP) by volatility, speed and how they are written.
  • Explain why programming flash can only change bits from 1 to 0, and why changing them back requires erasing a whole sector.
  • Compute the lifetime of a flash-based log from endurance, sector size, record size, write rate and the number of sectors used.
  • Describe how appending records and rotating sectors (wear levelling) extends flash life, and why EEPROM is often emulated this way.
  • State the practical constraints of writing flash that the program is executing from.
Before you start
  • AND, OR and masks on bytes (unit 2, lesson 1).
  • The blocks of a microcontroller and the flash and SRAM address ranges (lessons 1 and 3).
Steps in this lesson
  1. Two families: volatile and nonvolatile
  2. Erase to ones, program to zeros
  3. Endurance and retention
  4. EEPROM, real and emulated
  5. Worked example: storing a configuration for ten years
  6. Common misconceptions

The puzzle

A byte in flash reads 0x3C. Your code writes 0x5A to the same address, the write reports success, and reading back gives 0x18, a value nobody wrote. Nothing is broken. Flash is not RAM, and the rule it follows is simple, strict and completely unlike the memory your variables live in. What is the rule, and how do you store a setting that must survive ten years of power cycles when each piece of flash can only be rewritten a few thousand times?

STEP 1

Two families: volatile and nonvolatile

Volatile memory needs power to keep its contents. Nonvolatile memory keeps them with the power off. A microcontroller needs both: nonvolatile storage for the program and anything that must survive a reset, and volatile working memory that is fast and can be written freely.

MemoryKeeps data unpowered?ReadWriteTypical use
SRAMnofast, any bytefast, any byte, unlimitedvariables, stack, heap
NOR flashyesfast enough to execute fromerase a sector, then program pages; limited cyclesprogram, constants, logs
EEPROMyesslow-ish, any byteper byte, limited cycles (more than flash)settings
ROM (mask ROM)yesfastnever: fixed at manufactureboot code
OTP / fusesyesfastonce per bitkeys, calibration, configuration

SRAM holds each bit in a small latch of transistors that stays in one state while powered. Any byte can be written in one bus cycle, as often as you like. Remove power and the contents become indeterminate: they cannot be relied on, though they are not necessarily random either. Lesson 6 returns to what that means after reset.

Flash holds each bit as charge trapped in an insulated part of a transistor, which stays put for years without power. Reading it is fast enough to execute code from. Writing it is the hard part.

STEP 2

Erase to ones, program to zeros

Flash writes in two separate operations with two different sizes:

  • Erase sets every bit in a block to 1. The smallest erasable block is a sector: 4096 bytes on the flash chips the RP2040 SDK supports (FLASH_SECTOR_SIZE). Erased flash reads 0xFF.
  • Program can change 1s to 0s, but never 0s to 1s. It is done in pages: 256 bytes for the same chips (FLASH_PAGE_SIZE).

So the value left after programming is the old contents combined bitwise with the new value:

stored=old  &  new\text{stored} = \text{old} \;\&\; \text{new}

0x3C & 0x5A = 0x18, which is the puzzle from the opening. The SDK’s own documentation says it plainly: the only way to change a zero bit back to one is to erase the whole sector the page resides in.

The AND rule describes the external SPI NOR flash chips used with parts like the RP2040. Many microcontrollers’ internal flash adds error-correcting codes and forbids programming the same word or page twice between erases, even to clear more bits. Before relying on reprogramming a partly written page (the append scheme below does), check that your flash allows it.

↑ This step uses the figure at the top of the page.

This one rule shapes every piece of firmware that stores data. Updating one byte in place means erasing the whole 4096-byte sector, which erases the other 4095 bytes too, so they must be read into RAM first and written back. Erasing takes milliseconds, not nanoseconds. And if power fails between the erase and the rewrite, the old data is gone and the new data is not yet there (unit 14 lesson 5).

STEP 3

Endurance and retention

Each erase slightly damages the cells. The datasheet states two limits:

  • Endurance: how many erase/program cycles each erasable block is specified to survive. The ATmega328P datasheet, for example, specifies 10 000 cycles for its flash and 100 000 for its EEPROM.
  • Retention: how long data survives unpowered. The same datasheet gives 20 years at 85 °C and 100 years at 25 °C. Retention is shorter when hot and after many erase cycles; datasheets state the temperature, and often the number of cycles already endured, that a retention figure applies to.

Both are per-part numbers under stated conditions, exactly like the electrical limits in unit 1 lesson 6: use the numbers in your part’s datasheet, not these.

Endurance counts erases, and an erase covers a whole sector. That gives a lever. Instead of erasing to rewrite one record in place, append each new record after the last one in the sector, and erase only when the sector is full. With rr records per sector, rotating through SS sectors, each able to survive EE erases, and one record written every Δt\Delta t:

Tlife=E×S×r×ΔtT_{\text{life}} = E \times S \times r \times \Delta t

Rewriting in place is the special case S=r=1S = r = 1.

INTERACTIVEHow long flash lasts under repeated writes
Flash lifetime for in-place rewriting versus appending across several sectors, on a logarithmic time axis64 records fit in a 4096-byte sector before it must be erasedrewrite in place6.9 days4 sectors, appended4.9 years1 h1 d1 yr100 yr10k yr10-year product lifeLifetime = endurance × sectors × records per sector × interval = 10 000 × 4 × 64 × 1min ≈ 4.9 years, short of a 10-year life.
Flash lifetime for in-place rewriting versus appending across several sectors, on a logarithmic time axis64 records fit in a 4096-byte sector before it mustbe erasedrewrite in place6.9 days4 sectors, appended4.9 years1 h1 d1 yr100 yr10k yr10-year product lifeLifetime = endurance × sectors × records per sector× interval = 10 000 × 4 × 64 × 1 min ≈ 4.9 years,short of a 10-year life.
Record size
Endurance per sector
In place: 10 000 erases × 1 min ≈ 6.9 days. Appending 64 records per sector across 4 sectors: ≈ 4.9 years.

Each flash sector survives a limited number of erase cycles (the endurance, from the part’s datasheet). Rewriting one record in place costs an erase per write. Appending records until a sector is full, and rotating through several sectors, spreads the erases out: that is wear levelling. The model assumes 4096-byte sectors and ignores metadata overhead.

Spreading erases across the storage is called wear levelling, and it is what flash file systems such as littlefs are built around. Their design notes put the problem bluntly: writing to flash is destructive, and a system that keeps writing to the same block will wear it out.

STEP 4

EEPROM, real and emulated

A true EEPROM erases and writes single bytes and typically has higher endurance than flash, which makes it pleasant for settings: AVR parts provide eeprom_update_byte(), which writes only if the value has changed, precisely to save endurance. Many modern microcontrollers have no EEPROM at all. Vendors then supply “EEPROM emulation” libraries that do what the formula above suggests: keep a log of records in two or more flash sectors, always append, and copy the live values to a fresh sector when one fills up.

ROM and OTP complete the picture. The RP2040’s 16 KiB boot ROM is read-only memory fixed when the chip is made; firmware cannot corrupt it. One-time-programmable fuses can be written once per bit and are used for keys, calibration and security settings (unit 15).

STEP 5

Worked example: storing a configuration for ten years

A device keeps a 40-byte configuration and saves it up to 10 times a day. The flash specifies E=10 000E = 10\,000 erase cycles per 4096-byte sector. Will it last ten years?

Writes needed: 10×365.25×10=36 52510 \times 365.25 \times 10 = 36\,525 saves.

In place: every save erases the sector, so the sector lasts 10 00010\,000 saves, or 10 000/10=100010\,000 / 10 = 1000 days: about 2.7 years. It fails.

Appended records: give each record an 8-byte header with a sequence number and a checksum, so a record is 48 bytes and r=⌊4096/48⌋=85r = \lfloor 4096 / 48 \rfloor = 85 fit in a sector. One sector now absorbs 85×10 000=850 00085 \times 10\,000 = 850\,000 saves, more than 23 times the requirement. Using two sectors in rotation, so that a valid copy always survives while the other sector is erased, doubles that again. Lifetime: T=10 000×2×85×8640 s≈465T = 10\,000 \times 2 \times 85 \times 8640\ \text{s} \approx 465 years of daily writing, where 8640 s is one save every 2.4 hours.

The endurance limit stops being the constraint. What remains is power-loss safety, which the sequence numbers and checksums also provide: on boot, read every record, discard any whose checksum fails, and use the newest valid one.

MYTHS AND FACTS

Common misconceptions

Flash can be written like RAM

Programming can only clear bits. Setting any bit back to 1 needs a sector erase.

Erase sets memory to zero

Erased NOR flash reads as all ones (0xFF).

Endurance is per byte

It counts erase cycles of a whole sector. Appending records spreads one erase over many writes.

Reading flash wears it out

Endurance limits count erase/program cycles. Reads are not counted against them.

Retention is forever

It is a specified time, shorter at high temperature and for heavily cycled cells.

SRAM keeps its contents through a reset

It often does through a brief warm reset, but nothing guarantees it unless the chip documents it, and after power loss the contents are random (lesson 6).

Check yourself

Answer in your head, then open the card.

A flash byte holds 0xF0. What is stored after programming 0x3C without erasing? And after programming 0xC3?

0xF0 & 0x3C = 0x30. 0xF0 & 0xC3 = 0xC0. Neither is the value written, because both needed some 0 bits of 0xF0 to become 1.

Which new values can be programmed over 0xF0 without an erase?

Exactly those whose 1 bits are a subset of 0xF0’s: any value of the form 0xN0 where N’s set bits are within 0xF, i.e. 0x00, 0x10, 0x20, … 0xF0. Formally, new & ~old must be 0.

A logger writes one 32-byte record per second into 4096-byte sectors with 100 000-cycle endurance, rotating through 8 sectors. How long until the flash wears out?

r=4096/32=128r = 4096 / 32 = 128. T=100 000×8×128×1 s=102 400 000T = 100\,000 \times 8 \times 128 \times 1\ \text{s} = 102\,400\,000 s, about 3.2 years.

Why does erasing a sector to update one setting risk losing all the settings?

Erase clears all 4096 bytes. Between the erase and the reprogramming, the only copy of the other settings is in RAM; a reset or power failure in that window loses them. Appending to a second sector avoids ever erasing the only valid copy.

Sources (5)
  1. Raspberry Pi Ltd, pico-sdk 2.0.0, src/rp2_common/hardware_flash/include/hardware/flash.h — FLASH_PAGE_SIZE (1u << 8) and FLASH_SECTOR_SIZE (1u << 12); erase offsets must be 4096-byte aligned and programs 256-byte aligned; “Programming a flash page effectively changes some of the bits from one to zero. The only way to change a zero bit back to one is to ‘erase’ the whole sector”; the functions are unsafe while the other core or an interrupt handler executes from flash
  2. littlefs, DESIGN.md “The design of littlefs”, sections “The problem” and “Wear leveling” — why flash needs power-loss resilience and wear leveling: “Writing to flash is destructive. If a filesystem repeatedly writes to the same block, eventually that block will wear out”
  3. Microchip, ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B (Rev. B, 08/2020), “Features”, p. 1 — an example of endurance and retention specifications: write/erase cycles 10 000 for flash and 100 000 for EEPROM; data retention 20 years at 85 °C and 100 years at 25 °C
  4. Raspberry Pi Ltd, pico-bootrom-rp2040, bootrom/bootrom.ld — the boot ROM’s linker script: 16K of ROM at address 0
  5. avr-libc, include/avr/eeprom.h — byte-level EEPROM access (eeprom_read_byte, eeprom_update_byte) on parts with a true EEPROM; the update functions “read each byte first and skip the burning if the old value is the same”