Go Down

Topic: EEPROMex library - An extension of the standard Arduino EEPROM library (Read 44905 times) previous topic - next topic

kowalski


How does the program know/map the location of the variables when using EEMEM?
Or does it just start at address 0 etc?
But if I reorder my vars, does it reorder the mem addresses?

The Arduino EEPROM library requires you to keep track of the variables in memory. Using the attribute EEMEM works just as any other variable in global space (SRAM) but allocated in the EEMEM address space. The address of a variable is the answer to your first question. Second question, yes, the compiler/linker starts from address zero(0) in the EEPROM. Third, changing the order of EEMEM tagged variables will reorder them in EEPROM but you should be using the symbolic reference (&ex).

int ex EEMEM;
...
eeprom_write_word(&ex, 42); // &ex is the address to the variable
...
int x = (int) eeprom_read_word(&ex);

The actual address of the variable in EEPROM will be calculated by the compiler/linker when building the sketch. This means that libraries may have variables in EEPROM without forcing the library user to allocate them in the address space. This is what the Arduino EEPROM library forces. This is totally unreasonable for larger software systems with many components/libraries. This type of dependency must be avoided.

The AVR EEPROM support and GCC does the work for you.

Cheers!

kowalski


Quote
if you change the order in which you 'declare' the variables you mess it up

What I expected, thanks for the explanation

@robtillaart

Sorry for the very late reply. Missed your questions.

The bottom-line here is that when using the EEMEM attribute the variables become symbolic. Otherwise you are handling the eeprom address space yourself. Possible but tedious.

I wouldn't go as far as calling it a mess up when the compiler/linker remaps the variables when they are changed, removed, etc. The program should use the symbols and not care about the actual address.

Having that said there are some performance optimizations possible with eeprom as most devices have a page mode which is fast update of a "row" in the memory. Padding variables in page boundaries can give higher performance.  

Last, consider if the SRAM would be handled as the Arduino EEPROM library. Programmers would have to keep a map of the memory usage.

Cheers!

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

jabami

Hi there,

I need some help with the example code for the EEPROMex-library shown below:

Code: [Select]

#include <EEPROMex.h>

// ID of the settings block
#define CONFIG_VERSION "ls1"

// Tell it where to store your config data in EEPROM
#define memoryBase 32

bool ok  = true;
int configAdress=0;

// Example settings structure
struct StoreStruct {
    char version[4];   // This is for mere detection if they are your settings
    int a, b;          // The variables of your settings
    char c;
    long d;
    float e[6];
} storage = {
    CONFIG_VERSION,
    220, 1884,
    'c',
    10000,
    {4.5, 5.5, 7, 8.5, 10, 12}
};

void setup() {
  EEPROM.setMemPool(memoryBase, EEPROMSizeUno); //Set memorypool base to 32, assume Arduino Uno board
  configAdress  = EEPROM.getAddress(sizeof(StoreStruct)); // Size of config object
  ok = loadConfig();
}

void loop() {
  // [...]
  int i = storage.c - 'a';
  // [...]
  storage.c = 'a';
  if (ok)
    saveConfig();
  // [...]
}

bool loadConfig() {
  EEPROM.readBlock(configAdress, storage);
  return (storage.version == CONFIG_VERSION);
}

void saveConfig() {
   EEPROM.writeBlock(configAdress, storage);
}


I do not understand how to read one item from my store struct. If I try then I always get strange results. For example, what does the line
Code: [Select]

  int i = storage.c - 'a';

really do? It does not make much sense to me. Even if I output i over the serial monitor I only get strange results.

A more commented example would be very very helpful. Maybe one which reads and writes each element of the sorage struct. I just donĀ“t get it.
Thanks for any help in advance.

Greetings,
Jan

pjrc

#19
Aug 29, 2013, 10:22 pm Last Edit: Aug 29, 2013, 10:25 pm by Paul Stoffregen Reason: 1

The really bad new is that the Arduino build does not support the initialization of EEPROM. This is not uploaded with the sketch. Otherwise you could initialize the EEPROM variables directly.


I implemented this on Teensy 2.0.  In hindsight, it turned out to be less than ideal.

The main problem is when a user writes "EEMEM unsigned long my32bits;" they expect it to retain its value across code uploads.  But unfortunately, that's not how the compiler works.  It will create an EEMEM section with all uninitialized variables set to zero.  So when you build a tool like Teensy Loader (or hypothetically, some future version of Arduino) that automatically detects the EEMEM section and writes it to the eeprom, you wipe out the previous state on every upload.  That's technically the correct behavior based on the ELF file the compiler generates, but it isn't a behavior that makes Arduino users happy.  In fact, people generally hate it.

To really make this work in a way that users intuitively expect, what's needed are two EEMEM sections, perhaps EEMEM and EEMEM.NOINIT.  The variables without initialized values would go into the other section, which would not be overwritten during upload.  Initialized variables would get set to their specific value on every upload.

I may yet do this for Teensy3, because it uses a custom linker file, as is the norm when compiling for nearly all ARM chips.  For AVR, straying from the built-in linker script is just asking for big trouble.

mrTee

The previous version of the EEPROMex had a few bugs, which quite a few people reported. I had not expected the library to be used this much!  All in all, an update of the EEPROMex was long overdue. Today I packaged a version that includes many minor bugfixes as well as support for newer Arduino boards & the Teensy boards.

Special thanks to the people who have submitted updates, among which
- Paul Stoffregen - Newer Arduino boards and Teensy support as well as  multiple bugfixes
- NuclearCanary & John - Fix in bit storage logic

You can download the updated library here: 
  http://thijs.elenbaas.net/downloads/?did=3

oxedgar

Hi,

Thank you for your library. I have use it on a Arduino Mega2560 with succes!

But now i want to try it on Arduino Due. It is possible ? or exists another one issue for this?

tanks for reply
Arduino's, RaspBerry Pi's b and b+, Domoticz, Imperihome
topic: http://forum.arduino.cc/index.php?topic=292994.0

pert

But now i want to try it on Arduino Due.
The microcontroller used on the Due doesn't have internal EEPROM. You could add an external EEPROM chip, use flash memory as EEPROM, or I saw a demonstration of using the EEPROM on the ATmega16U2 used on the DUE for USB serial:
http://forum.arduino.cc/index.php?topic=191298

None of those options will be directly supported by the EEPROMex library.

pert

An important note for users of the EEPROMex library:

The version available via Library Manager, release version 1.0.0 on GitHub, and the version available from thijs.elenbaas.net all have debug mode enabled by default. This means that, unless you have changed the value via setMaxAllowedWrites(), the library stops writing to EEPROM after 100 writes. This can be very confusing if you have not read the documentation on the website or the source code to learn of this feature. The Serial debug code also uses a lot of memory. Debug mode has now been turned off by default but there has not been a new release since that change.

Go Up