Skip to content

mskstanmay/Virtual-EEPROM---Flash-Memory-Emulation

Repository files navigation

Virtual EEPROM

Virtual EEPROM is a portable C11 library that emulates a linear EEPROM-style byte array on top of erase-before-write flash memory. It is intended for embedded systems that need predictable persistence semantics, explicit recovery behavior, and a small firmware-friendly integration surface.

The library is designed around a few non-negotiable goals:

  • No hidden global mutable state
  • No heap allocation in the core library
  • Clear, explicit lifecycle semantics
  • Deterministic recovery after interrupted page migration
  • Host-side validation through simulation and automated tests

Overview

The public API presents a logical byte-addressable storage region. Internally, the library persists data as fixed-size block records, where the block size is equal to the configured flash program unit. This keeps the flash model honest while allowing the external interface to remain simple.

Each active flash page contains a self-consistent logical snapshot. When the page fills, the library migrates the latest committed block image into a scratch page, commits the new page, and retires the old page. That approach favors correctness and recoverability over peak write throughput, which is the right trade-off for a first production-quality implementation.

Additional design detail is documented in [architecture.md](/T:/Git Repos/Virtual EEPROM & Flash Memory Emulation/docs/architecture.md), [flash_layout.md](/T:/Git Repos/Virtual EEPROM & Flash Memory Emulation/docs/flash_layout.md), and [decisions.md](/T:/Git Repos/Virtual EEPROM & Flash Memory Emulation/docs/decisions.md).

Key Characteristics

  • Heap-free core library using caller-owned instance memory
  • Opaque device handle with injected flash callbacks
  • Explicit veeprom_mount() and veeprom_format() behavior
  • No implicit formatting of blank media
  • Synchronous writes with recovery-aware page migration
  • Host simulator with deterministic fault injection
  • Unit, integration, recovery, endurance, and install-tree smoke tests

API Model

Typical use follows this sequence:

  1. Populate veeprom_config_t with flash geometry and callback functions.
  2. Allocate aligned instance memory sized with veeprom_instance_size().
  3. Call veeprom_init().
  4. Call veeprom_mount() to scan existing flash contents.
  5. If mount returns VEEPROM_STATUS_UNFORMATTED, call veeprom_format().
  6. Use veeprom_read() and veeprom_write() against the logical byte array.

Important behavioral notes:

  • veeprom_mount() scans existing media only. It never erases flash implicitly.
  • veeprom_format() creates a new empty logical image and leaves the device mounted.
  • veeprom_flush() is present as a stable API boundary, but writes are synchronous in v1.
  • Writes are committed one internal block record at a time. A write spanning multiple internal blocks is not transactional across the entire request.

Example

#include <stdint.h>
#include "veeprom/veeprom.h"

static uint8_t device_memory[2048];

int initialize_store(const veeprom_flash_if_t *flash_if, veeprom_device_t **out_device)
{
    veeprom_config_t config = {
        .geometry = {
            .flash_base_address = 0U,
            .page_size_bytes = 512U,
            .page_count = 4U,
            .erase_size_bytes = 64U,
            .program_unit_bytes = 8U,
        },
        .flash_if = flash_if,
        .logical_size_bytes = 64U,
        .erased_value = 0xFFU,
    };

    veeprom_status_t status;

    status = veeprom_init(device_memory, sizeof(device_memory), &config, out_device);
    if (status != VEEPROM_STATUS_OK)
    {
        return -1;
    }

    status = veeprom_mount(*out_device);
    if (status == VEEPROM_STATUS_UNFORMATTED)
    {
        status = veeprom_format(*out_device);
    }

    return (status == VEEPROM_STATUS_OK) ? 0 : -1;
}

See [examples/host_basic/main.c](/T:/Git Repos/Virtual EEPROM & Flash Memory Emulation/examples/host_basic/main.c:1) for a host-side example using the simulator backend.

Build

cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failure

CMake Options

  • VEEPROM_BUILD_TESTS: build the automated test suite
  • VEEPROM_BUILD_SIMULATOR: build the host-side flash simulator and CLI
  • VEEPROM_BUILD_EXAMPLES: build example applications
  • VEEPROM_ENABLE_WARNINGS: enable strict warning profiles
  • VEEPROM_ENABLE_SANITIZERS: enable host-side sanitizer instrumentation

Repository Layout

include/veeprom/     Public API headers
src/                 Core library implementation
tests/               Unit, integration, recovery, endurance, and packaging tests
tools/simulator/     Host-side simulator support and CLI
examples/host_basic/ Minimal example application
docs/                Architecture, layout, and design rationale
cmake/               Shared CMake helpers

Limitations And Assumptions

  • v1 assumes erased flash reads as 0xFF.
  • The configured logical image must fit into one fully populated active page.
  • The core library is portable C11, but the simulator and CI are host-oriented.
  • Multi-block user writes are not atomic as a single transaction.

Status

The repository currently contains a complete v1 core implementation, host-side simulation support, automated tests, and CI scaffolding. The library is shaped as a production-oriented embedded component, with emphasis on clarity and reviewability over aggressive optimization.

About

Embedded flash memory emulation library providing a virtual EEPROM layer with wear leveling, power-loss resilience, and persistent key-value storage in C/C++.

Topics

Resources

License

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Contributors