charlesbaynham / OSFS

Overly Simplified File System for Arduino EEPROM
GNU General Public License v3.0
33 stars 9 forks source link

Handle multiple memories #11

Open ferchinas opened 4 years ago

ferchinas commented 4 years ago

Hi @charlesbaynham: Your library is just what I had in mind, I was glad to find it. I would like to add more than one external memory to my project. An EEPROM memory and a FRAM. But I see that the interface is through static methods, so I imagine that it is not possible to define several instances of it, one for each type and size of memory. Am I right?

charlesbaynham commented 4 years ago

Hi!

That's an interesting use case, but I'm afraid you're right: as currently written there's no support for multiple memories. I reckon this could be done by creating an object as an interface to your memory, which you initialise with pointers to the reader/writer methods instead of defining them statically as is currently done. That's quite a refactor to the current library though, and would add complexity for users who don't need the feature.

What you could do to work around the problem is switch those four static members of OSFS when you need to change memories. Something like (EDIT: this won't work)

void readNBytesFromFRAM(uint16_t address, unsigned int num, byte* output) {
    ...
}
void readNBytesFromEEPROM(uint16_t address, unsigned int num, byte* output) {
    ...
}

void switchToFRAM() {
    OSFS::readNBytes = readNBytesFromFRAM;
    OSFS::writeNBytes = writeNBytesToFRAM;
    OSFS::startOfEEPROM = FRAMStart;
    OSFS::endOfEEPROM = FRAMEnd;
}

With accessing functions written for both read and write, for both types of memory. OSFS doesn't retain any state between calls, so altering those four variables will set it up for whichever memory you want to use.

charlesbaynham commented 4 years ago

Actually, that won't work: I've been programming in python too much recently so I've forgotten that c++ won't let you do that.

However, you could still do something like:

bool in_FRAM_mode = false;
void OSFS::readNBytes(uint16_t address, unsigned int num, byte* output) {
    if (in_FRAM_mode) 
        return readNFRAMBytes(address, num, output);
    else
        return readEEPROMBytes(address, num, output);
}

Then you could switch modes by changing startOfEEPROM, endOfEEPROM and in_FRAM_mode.

ferchinas commented 4 years ago

Excellent, it makes a lot of sense. I had thought what you mentioned making an interface with an object for each memory, so it would be more flexible. But the other option you propose is much easier. With this information you give me it will be easier to immerse myself in your code. I will try what you recommend and share the results Thanks!

charlesbaynham commented 4 years ago

Let me know how it goes!