Skip to main content

Flash memory and IAP

Segment and sector

The two words are used loosely but describe different things.

Sector

The basic erasable unit of physical flash memory. In an MCU's flash, a sector is the smallest region that can be erased independently — erasing anything means erasing at least one whole sector.

Sizes are fixed by the hardware and are often not uniform across the device. STM32 parts commonly use small sectors at the start of flash and much larger ones further in; 16 KB, 64 KB and 128 KB in the same device is typical.

The defining property is that an erase clears the entire sector. Flash cells can only be programmed in one direction, so a byte cannot be rewritten without erasing everything around it first.

Segment

A logical division of address space, defined by software rather than hardware. In a linker script a segment (.text, .data, .bss, or a custom one) is a range of addresses reserved for a particular purpose: code, initialised data, stack, heap.

Segments are configurable. Their size and placement come from the linker script and can be chosen to suit the application.

In practice

Sector is about hardware and erase strategy; segment is about how software organises memory. During flashing you will see "erasing sectors" for physical flash regions, while "memory segments" describes where the linker placed code and data.

The two interact the moment a segment has to be erased at run time, which is what IAP does.

In-application programming

Firmware that erases and rewrites part of its own flash, so a device can be updated without a debugger. The usual layout is a small bootloader in the first sectors plus one or two application slots.

Data disappears when flashing

When splitting the flash regions in the *.ld linker script, respect the hardware's erase granularity. The sector is the smallest erasable unit — 16 KB, 64 KB or 128 KB depending on the part and on where in flash the sector sits.

If a region boundary falls inside a sector, erasing one region also erases whatever shares that sector. Data written to a configuration or parameter area then vanishes the moment the application area is reprogrammed, and the symptom appears only after an update rather than during development.

Every region boundary must fall on a sector boundary:

Sector 0 0x08000000 16 KB bootloader
Sector 1 0x08004000 16 KB bootloader
Sector 2 0x08008000 16 KB parameters <-- own sector, safely erasable
Sector 3 0x0800C000 16 KB reserved
Sector 4 0x08010000 64 KB application
Sector 5 0x08020000 128 KB application
...

Sector sizes and addresses are in the reference manual for the specific part — "Embedded Flash memory" — and they differ even between devices in the same family. Dual-bank parts add a second consideration: the banks have their own sector numbering, and erasing by sector number without specifying the bank hits the wrong one.

Points to check

  • Vector table relocation. The application's vector table is no longer at the start of flash, so SCB->VTOR must be set to its base address before interrupts are enabled. Forgetting this gives a bootloader that jumps successfully and then faults on the first interrupt.
  • De-initialise before jumping. Disable interrupts, stop SysTick, disable the caches and reset any peripheral the bootloader started. The application expects reset-state hardware, and a still-running DMA channel or timer interrupt lands in a vector table that has moved.
  • Invalidate the I-Cache before jumping into freshly programmed flash. The cache may still hold lines fetched from the old image at the same addresses.
  • Flash cannot be read while it is being written. Code that erases or programs flash must execute from RAM if it lives in the same bank. On single-bank parts this applies to the whole flash; on dual-bank parts the other bank stays readable, which is what makes safe field updates practical.
  • Power loss during an update. An interrupted write leaves the slot invalid. Either keep two application slots and switch only after verification, or keep the bootloader able to re-enter update mode unconditionally.
  • Verify before committing. Check a CRC or a signature over the received image before marking it bootable. See Secure OTA with code signing for the signing side of the same problem.
  • Write alignment. STM32 flash programs in fixed units — 32 bytes on the H7, 8 bytes on many others. Writes must be aligned and complete; a partial write to an already-programmed word fails or corrupts ECC.
  • Unlock and re-lock. HAL_FLASH_Unlock() before any erase or program, HAL_FLASH_Lock() afterwards. Leaving flash unlocked means a wild pointer can corrupt the firmware itself.

Option bytes and read protection

Read-out protection (RDP) is set through the option bytes, not the linker script, and it has a one-way step:

  • Level 0 — no protection.
  • Level 1 — flash is unreadable over the debug port; regressing to level 0 mass-erases the flash. Reversible, at the cost of the contents.
  • Level 2 — the debug port is disabled permanently. There is no way back, including for you. A part in level 2 with broken firmware is scrap.

Set level 2 only on production images, and only once the update path has been proven on real hardware.