EEPROM - writing many files, indexing addresses

How can I create an index of file locations (addresses) in EEPROM where my files were stored (written)?

It should be something like starting from index (location) 0, and going on for the length of the object/struct, Then once you know that length, you can add an empty byte, ad start the next file. BUT you need to know the address of the next file, and it's length(?) in order to read it, or anything else...

[Address]
start stop
0 238 a struct taking up 239 bytes
239 239 a blank byte to separate
240 261 a struct taking up 21 bytes
262 262 a blank byte to separate
263 263 a 1 byte primitive object
[...]

..and we haven't even talked about storing the index in the EEPROM itself...

Is there a flow/set of steps/code to determine the size of objects (primitives & structs), such that lots of data/structs can be stored/accessed on a single chip?

TIA!

not sure about the necessity of the blank byte...

so your "struct" is of variable size?

I would use a linked list where the header contains a link to the start of the next file or one that shows it is the last file.

Search for Linked List for more information.

You could have at the start the number of entries

then the struct you store contains first it's size on a given number of bytes that is known (say one byte if the length is always less than 255) and then the variable size payload.

EEPROM would look like
43ABC5DEFGH1I6JKLMNO

resizing an entry will not be fun though :wink:

you could also go with "fixed size" struct and pad with 0 the unused data

You may want to consider using avr eeprom functions
https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html

When you use #include <avr/eeprom.h> and the EEMEM attribute, the memory addresses are managed by the compiler.

Here's a simple example

#include <avr/eeprom.h>

int myValuePos = 12345;//int in sram
int myValueNeg = -12345;

EEMEM uint16_t saveMyValuePos; //integer in eeprom; avr will control address
EEMEM uint16_t saveMyValueNeg;

//uint16_t address = 0X05;

void setup()
{

  Serial.begin(9600);

  //eeprom_write_word( (uint16_t*)address , myValue+);
  eeprom_write_word( & saveMyValuePos , myValuePos);
  eeprom_write_word( & saveMyValueNeg , myValueNeg);


  //int val =eeprom_read_word(& address);
  int valPos =eeprom_read_word(& saveMyValuePos);
  int valNeg =eeprom_read_word(& saveMyValueNeg);


  Serial.println(valPos);
  Serial.println(valNeg);
}

void loop()
{
}

We don't know if OP is using an AVR :wink:

define one struct for all your eeprom variables.

than you can access each member with EEPROM.put and EEPROM.get.
If you need the "address", you can use "offset".

and by the way, imho these two bytes are wasted EEPROM space:

239 239 a blank byte to separate
262 262 a blank byte to separate

your controller doesn't have eyes. It doesn't need blanks between your data.

I'm targeting Espressif esp32, but a solution for any chip would be helpful for others.

so your "struct" is of variable size?

Right now, just configurations. So I could just make them a fixed size, leaving room for expansion.

not sure about the necessity of the blank byte...

In other storage mediums, a character for delimiting is key when troubleshooting. Should that be a "0"? Probably not... A high ASCII char stands out more.

EEPROM.h has deprecated for this platform.

Use Preferences.h instead. It is a library bundled in the Arduino core, and it uses Key/Value pairs and manages the addresses. It also does wear leveling and NVS memory management.

https://github.com/espressif/arduino-esp32/tree/master/libraries/Preferences