For device OS 4.2.0, I'm trying to write a function that writes a variable amount of bytes to the emulated EEPROM using EEPROM.put(address, object). In my implementation, it appears that the struct that is passed needs to be statically defined ahead of time. What's the recommended way to achieve this? I've come up with two ideas and wanted to point out the issues with each that I encountered.
Putting fixed blocks of 64 bytes and then writing individual bytes one-by-one that don't fit into the block size. The problem is there's a delay for each EEPROM.put() or EEPROM.write() call, which I imagine is because the whole file is being written at once per documentation. The only improvements I could think of is to make multiple block sizes to prevent the least amount of writes.
Reading the full 4096 bytes into a struct, modifying the necessary bytes, the writing the whole 4096 byte struct. This is fast, but there was software that worked before, but it goes into SOS Panic mode when it gets to the EEPROM.get() call in some cases.
Ideally, it'd be great if there was a way to pass a pointer and a size so the writes could be variable for EEPROM.put(address, pointer, size).
Like Gus said, using the file system API is the correct solution here. On Gen 3 devices including the Monitor One, writing to the EEPROM just writes the data to a file on the same flash file system anyway, so the performance will be nearly identical.
However the file system API is designed to write variably-sized data easily.
I checked with the customer, and they need at least part of what they're storing on an EEPROM. So, I think I might have to go with the I/O card's EEPROM. Thank you!
I saw this example. Is this still the way to go about it?
Hi, I would insist, since it's the same thing. Whatever you write in the file system will survive resets, absence of power. And these days EEPROM is simulated and uses the file system under the hood.
Perhaps the customer has another requirement that of course I am unaware of.
The Tracker SoM has a flash memory chip on it, part of which contains a flash file system for persistent data (4 MB).
Instead of adding another EEPROM chip, the EEPROM calls just write to that flash file system. It's really fast quad SPI flash, it's much faster than a real EEPROM.
Yes, but that's not really intended for user data storage. It's designed to hold the card ID or maybe card-specific calibration data. It's 8 Kbytes and relatively slow.
If you do really want to use it, the first 64 bytes are reserved for this structure; make sure you don't overwrite it.
struct ExpansionEeprom1 {
uint16_t size; ///< Size of entire ExpansionEeprom
///< structure. LSB, MSB
uint8_t revision; ///< Revision number of this hardware
///< starting from 1
char sku[29]; ///< SKU name with null termination
uint8_t serial[16]; ///< 128-bit serial number MSB->LSB
uint8_t reserved[16]; ///< Page boundary filler
} __attribute__((packed));
There's more information in the README in Monitor Edge. There are functions in eeprom_helper.h to read and write it.