Skip to content

burakenez/eemul

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

1 Commit
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

โšก EEMUL โ€” Flash-Backed EEPROM Emulation Middleware

GitHub tag (latest by date) License: MIT Language: C Platform: Embedded Status: Stable

โœจ EEMUL is a portable, robust, and configurable EEPROM emulation library for microcontrollers that lack built-in EEPROM.
It leverages on-chip Flash to provide persistent parameter storage with:

  • ๐Ÿ›ก๏ธ Atomic commits
  • ๐Ÿ”„ Wear leveling
  • โŒ Bad-block handling
  • ๐Ÿ“ฆ Flexible block modes
  • ๐Ÿงพ Descriptor-based layout

โœจ Features

  • ๐Ÿ›ก๏ธ Atomic commit protocol โ†’ prevents corrupted states after power loss.
  • ๐Ÿ”„ Wear leveling (rotate) โ†’ spreads writes evenly across blocks.
  • โŒ Bad-block resilience โ†’ skip or permanently mark failing pages.
  • ๐Ÿ“ฆ Multiple block modes:
    • Page mode โ†’ one Flash page = one block (simple).
    • Sub-block mode โ†’ multiple blocks per page (space efficient).
  • ๐Ÿ“ Header flexibility โ†’ compact (16B) or full (32B) headers.
  • ๐Ÿงพ Descriptor-driven storage โ†’ define parameter sizes once, library handles offsets.
  • ๐Ÿ› ๏ธ Shadow buffer in RAM โ†’ enables differential writes & no-op suppression.
  • โš™๏ธ Configurable buffer strategy โ†’ static arrays (ROM friendly) or dynamic alloc (flexible).
  • ๐Ÿ”Œ Portable HAL port layer โ†’ implement erase/program/read (CRC optional).

๐Ÿ—๏ธ Architecture Overview

  • ๐Ÿ”น Reserved Flash region is divided into logical blocks.
  • ๐Ÿ”น Each block = Header + Payload snapshot.
  • ๐Ÿ”น At runtime:
    1. ๐Ÿ“ Locate latest valid committed block.
    2. ๐Ÿ“ฅ Load payload into RAM shadow buffer.
    3. โœ๏ธ On updates, create a new block (erase โ†’ precommit header โ†’ program payload โ†’ finalize commit).
  • ๐Ÿ”ข Sequence counters ensure monotonic versioning.

โšก Power-loss safe: only blocks with commit_flag=0x00000000 are treated as valid.


๐Ÿ“ Memory Layout

Page Mode

[ Page 0 ] => Block0 (Header + Payload)
[ Page 1 ] => Block1 (Header + Payload)
...

Sub-block Mode

[ Page N ]
+---------+---------+---------+
| Block0  | Block1  | Block2  |
| H + P   | H + P   | H + P   |
+---------+---------+---------+
  • Page mode โ†’ simple alignment, fewer blocks.
  • Sub-block mode โ†’ better density, useful when payload is small vs page size.

๐Ÿ“‘ Header Options

Mode Size Fields Use case
Compact 16B magic, sequence, CRC, commit Space efficient
Full 32B magic, sequence, CRCs, payload len, bad-marker, commit flag Max integrity

๐Ÿ”ฎ Magic constants:

  • Full header โ†’ "EEMULATE" (64-bit ASCII).
  • Compact header โ†’ "EMUL" (32-bit ASCII).

โš™๏ธ Configuration Macros

#define EEMUL_REGION_END_ADDR       0x08010000U   // Region end address (exclusive)
#define EEMUL_NUMBER_OF_FLASH_PAGES 2U            // Reserved pages
#define EEMUL_FLASH_PAGE_SIZE       0x400U        // 1KB per page
#define EEMUL_ALIGN_BYTES           4U            // Program alignment
#define EEMUL_ENABLE_DYNAMIC_ALLOC  1U            // Use malloc/calloc for buffers
#define EEMUL_USE_FULL_BLOCK_HEADER 1U            // 1=full (32B), 0=compact (16B)

Derived:

  • ๐Ÿงฎ EEMUL_REGION_SIZE_BYTES = PAGES ร— PAGE_SIZE
  • ๐Ÿงฎ block_bytes = align_up(header + payload, PAGE_SIZE)
  • ๐Ÿงฎ blocks_count = REGION_SIZE / block_bytes

๐Ÿงพ Descriptor Example

typedef uint8_t eemul_version_t[4];
typedef uint8_t eemul_statistics_t[20];
typedef uint8_t eemul_counter_t[1];
typedef uint8_t eemul_error_log_item_t[1];

const uint8_t s_descriptor[] = {
  /* ID 1: FW version */
  sizeof(eemul_version_t),
  /* IDs 2..12: error log entries */
  sizeof(eemul_error_log_item_t), sizeof(eemul_error_log_item_t), /* ... */
  /* ID 13: statistics page */
  sizeof(eemul_statistics_t),
  /* ID 14: counter */
  sizeof(eemul_counter_t)
};

๐Ÿš€ Quick Start

// 1๏ธโƒฃ Provide Flash ops
const eemul_port_ops_t ops = {
  .erase_page = my_erase,
  .program    = my_prog,
  .read       = my_read,
  .crc32      = NULL // SW CRC fallback
};

// 2๏ธโƒฃ Configure
eemul_handle_t h;
const eemul_init_config_t cfg = {
  .badblock_policy  = EEMUL_BADBLOCK_POLICY_MARK,
  .block_mode       = EEMUL_BLOCK_MODE_SUBBLOCKS,
  .bad_retry_threshold = 2,
  .enable_monotonic_sequence  = true,
};

// 3๏ธโƒฃ Init
eemul_init(&h, &ops, &cfg, s_descriptor, sizeof(s_descriptor));

// 4๏ธโƒฃ Write parameter
uint32_t val = 0x12345678;
eemul_write_param(&h, 0, &val, sizeof(val));

// 5๏ธโƒฃ Read parameter
val = 0;
eemul_read_param(&h, 0, &val, sizeof(val));

๐Ÿงช Testing Utilities

Two built-in test modes:

  • ๐Ÿ“ Region fill test โ†’ sequential writes until the emulation region is full.
  • ๐Ÿ”„ Overflow test โ†’ observe behavior after storage exceeds capacity.

Logs include:

  • ๐Ÿ”ข Active block index + sequence
  • ๐Ÿ“ Active block address
  • โœ… Read-back verification

๐Ÿ”Œ Porting Layer (eemul_port)

Minimal hooks to implement per MCU:

bool erase_page(uint32_t addr);
bool program(uint32_t addr, const void *src); // size = EEMUL_ALIGN_BYTES
void read(uint32_t addr, void *dst, uint32_t len);
uint32_t crc32(const void *data, uint32_t len); // optional

Template: eemul_port_template.c demonstrates GD32 implementation.


๐Ÿ“‚ Repository Structure

โ”œโ”€โ”€ eemul.h               # Public API & configuration
โ”œโ”€โ”€ eemul.c               # Implementation
โ”œโ”€โ”€ eemul_port.h          # Port interface definition
โ”œโ”€โ”€ eemul_port_template.c # Example port
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ eemul_test.h      # Test declarations
โ”‚   โ”œโ”€โ”€ eemul_test.c      # Region fill & overflow tests
โ””โ”€โ”€ README.md             # Project documentation

๐Ÿค Contributing

๐Ÿ’ก Contributions are welcome:

  • ๐Ÿ› Report issues & suggest improvements.
  • ๐Ÿด Fork and submit pull requests.
  • ๐Ÿงช Extend tests, add new port templates, or propose features (e.g., encryption).

๐Ÿ“œ License

Released under the MIT License.
Use freely in personal, academic, and commercial projects.


๐Ÿ”ฅ EEMUL โ€” reliable EEPROM emulation on any MCU, with Flash-backed safety.

About

EEMUL is a portable EEPROM emulation for MCUs using Flash with atomic commits, wear leveling, bad-block handling, and descriptor-based layout.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages