How to implement data storage and management in embedded systems?

2025-10-16 15:13:52

Here’s a practical, “from blank board to production” blueprint for data storage & management on embedded systems. Skim the bold headings first; dive where you need details.

How to implement data storage and management in embedded systems?

1) Start with a data brief (5 questions)

Write this down before you pick any tech:

  • What do you store? (configs, logs, sensor data, ML params, firmware)

  • How much total and per write? (bytes…MB)

  • How often do you write? (Hz / per day)

  • How long must it survive power-offs & heat? (retention, temp)

  • How safe must it be? (integrity, security, regulatory)

2) Pick the memory technology

Need Good fits Notes
Small configs (≤16 KB), rare writes MCU internal Flash (EEPROM emulation), EEPROM Use wear-leveled driver; don’t rewrite same page.
Frequent tiny writes FRAM / MRAM “No-erase” and very high endurance; simple drivers.
Code XIP + small data QSPI/OSPI NOR Flash Fast reads; erase in 4–64 KB sectors; 50–100k P/E typical.
Large data/logs (MB-GB) NAND, eMMC, SD Needs FTL/wear leveling; expect bad blocks (raw NAND).
High bandwidth + OS eMMC/UFS Built-in controller handles FTL/ECC; simpler than raw NAND.

3) Decide the storage topology

  • Raw flash (NOR/NAND) → FTL/wear-level → FS or KV store

  • Managed media (eMMC/SD) → FS directly (FAT/ext/F2FS)

  • NVRAM (FRAM/MRAM) → raw records / KV (no FTL needed)

Use a partition map (even on MCUs):

  • bootloader | fw_A | fw_B (OTA) | factory_cal | kv_config | logs | user_data

4) Filesystem vs Key-Value vs Raw

Key-Value (KV) store (recommended for configs)

  • Pros: tiny footprint, atomic, easy wear leveling.

  • Examples: littlefs (has directories + KV style), ESP-IDF NVS, Zephyr settings, STM32 EEPROM emulation app notes.

Filesystems

  • littlefs (NOR): copy-on-write, power-fail safe, great for ≤16 MB.

  • SPIFFS (NOR): lightweight; no directories; aging project.

  • FAT/exFAT (SD/eMMC): ubiquitous & PC-friendly; add journaling layer for power-fail safety.

  • UBIFS/YAFFS2 (raw NAND, Linux): handle bad blocks & wear leveling.

  • F2FS/ext4 (eMMC/UFS, Linux): log-structured/ext with journaling.

Raw append-only logs / ring buffers

  • Best for telemetry and black-box logs; you manage indexing, CRC, rollover.

5) Wear leveling & endurance

  • Never update-in-place on flash sectors; use copy-on-write or log-structured writes.

  • Rotate erase blocks (dynamic leveling). Keep hot data (counters) in FRAM if possible.

  • Budget writes against endurance (e.g., 50–100k P/E NOR; eMMC/NAND varies by grade).
    Tip: move high-churn data (e.g., uptime counters) to FRAM or to a journal page that rotates.

6) Data integrity: make corruption boring

  • Per-record CRC/CRC32 (or AEAD tag if encrypted).

  • Atomic commit pattern: write header → data → CRC → flip commit bit/sequence.

  • Prefer journaling / copy-on-write FS (littlefs, UBIFS, ext4 journaled).

  • Add ECC where available (BCH/LDPC in NAND, eMMC controller built-in).

7) Power-fail safety

  • Keep writes small and bounded; avoid multi-page “transactions”.

  • Use double buffering or A/B records with monotonically increasing version/counter.

  • Hardware assists: brown-out reset (BOR), PMIC POK, optional supercap to flush last block.

  • Test with yank-the-plug campaigns at random write times.

8) Concurrency & RTOS integration

  • Use a single storage task with a message queue (producer/consumer); it serializes access.

  • Gate the block device with a mutex; keep critical sections short.

  • Use DMA for SD/eMMC; align buffers to cache lines; flush/invalidate caches on MMU systems.

9) Performance & footprint

  • Batch tiny writes into a write buffer (e.g., 512–2048 bytes).

  • Choose page/sector-aligned structures; avoid read-modify-erase loops.

  • Keep FS cache small but nonzero; e.g., littlefs block cache = 1–4 blocks.

10) Security (when data matters)

  • Secure boot for firmware partitions; rollback protection (monotonic counter).

  • Encryption at rest for sensitive data: AES-GCM/XTS, keys in HUK/PUF/TPM/TrustZone.

  • Per-record nonce + auth tag; consider key rotation and sealed storage APIs (TEE).

11) OTA & versioned data

  • Use A/B firmware slots + small boot control KV with a trial-boot flag.

  • Store schema version with each dataset; include migrations on upgrade.

  • Keep factory calibration in a protected, rarely-erased area.

12) Data formats that work on MCUs

  • TLV (Type-Length-Value): tiny and robust.

  • CBOR (small, self-describing) or protobuf-nano/flatbuffers for bigger MCUs.

  • Always pack a magic, version, length, CRC, timestamp.


Minimal, robust patterns

A) Power-safe KV record (copy-on-write on NOR/FRAM)

 
typedef struct { uint32_t magic, ver, key, len; uint32_t seq; } hdr_t;
// Write sequence: HEADER (with seq+1) → DATA → CRC → COMMIT byte
bool kv_put(uint32_t key, const void* data, uint32_t len) {
  uint32_t seq = read_latest_seq_for_key(key);
  hdr_t h = {.magic=0x4B565A31, .ver=1, .key=key, .len=len, .seq=seq+1};
  // append to log area at next free offset
  append(&h, sizeof(h));
  append(data, len);
  uint32_t crc = crc32(&h, sizeof(h), data, len);
  append(&crc, 4);
  uint8_t commit = 0xA5;         // final, single-byte commit mark
  append(&commit, 1);
  return true;
}

Recovery: scan from the end; last record with valid CRC and commit mark wins.

B) Ring logger (fixed-size records)

 

#define REC_BYTES 64
typedef struct { uint32_t magic, seq, ts, crc; uint8_t payload[REC_BYTES-16]; } rec_t;

void log_write(const void* src, uint32_t ts) {
  rec_t r = { .magic=0x11445522, .seq = next_seq(), .ts = ts };
  memcpy(r.payload, src, sizeof(r.payload));
  r.crc = crc32(&r, sizeof(r)-4, NULL, 0);
  flash_write(aligned_ptr(), &r, sizeof(r));   // advances with wrap-around
}

C) LittleFS on external QSPI NOR (bare-metal sketch)

  • Partition NOR into lfs area (multiple erase blocks).

  • Mount with small caches and wear-level config; store configs in a single JSON/TLV file; logs in /log/ rolling files.

 
lfs_config cfg = {
  .read  = qspi_read, .prog = qspi_prog, .erase = qspi_erase, .sync = qspi_sync,
  .read_size = 16, .prog_size = 16, .block_size = 4096,
  .block_count = 2048, .cache_size = 64, .lookahead_size = 64, .block_cycles = 100
};
lfs_mount(&lfs, &cfg) || lfs_format(&lfs, &cfg);

Platform hints (common stacks)

  • STM32 (bare-metal/FreeRTOS): FATFS + wear-level for SD/eMMC; ST app notes for EEPROM emulation in Flash; littlefs via CubeMX middleware or open-source ports.

  • ESP32: NVS (KV store) on SPI flash; FATFS with wear-leveling driver; OTA with A/B provided by ESP-IDF.

  • Zephyr RTOS: settings (KV on NVS), littlefs/fcb (flash circular buffer), mcuboot for secure A/B OTA.

  • Linux SBC (e.g., i.MX, Zynq): ext4/F2FS on eMMC; UBIFS on raw NAND; use journald or your own ring logger for telemetry.


Validation & test checklist

  • Endurance plan: compute estimated daily writes vs device P/E and confirm margin.

  • Power-pull tests: hundreds of random pulls during active writes; zero-brick criteria.

  • Fault injection: flip bits in staged images, corrupt CRCs, simulate bad blocks.

  • Aging/thermal: soak tests at temperature corners; verify retention & boot times.

  • Security tests: verify rollback protection, key sealing, and tamper responses.

  • Field telemetry: include counters (erase cycles, mount failures, recovery count).


Quick decision guide

  • Just configs, rare writes: NVS/KV on internal flash (wear-leveled) → done.

  • Configs + small logs, power-safe: littlefs on QSPI NOR + ring logger.

  • Lots of data or high write rate: eMMC/SD with ext4/F2FS (Linux) or FAT + journaling layer (RTOS) + periodic checkpoints.

  • High-churn tiny writes: add FRAM/MRAM for hot variables; keep flash for bulk.

Harendra Kumar
Harendra Kumar
Harendra Kumar holds a Ph.D. in Electrical Engineering with a specialization in power electronics. His academic expertise and years of experience allow him to break down complex concepts into clear, actionable information for his audience. Through his work, he aims to bridge the gap between advanced technology and its real-world applications. Harendra is an accomplished writer who specializes in creating high-quality, long-form technical articles on power electronics for B2B electronics platforms. His content combines deep technical knowledge with practical insights, making it a valuable resource for professionals in the electronics industry.