EEMEM

Ok, so EEMEM does not define a variable, it is used by the compiler to infer an EEPROM address and it's type is used to understand the number of bytes it has to reserve to store one of those.

Whatever I put beside EEMEM is not going to occupy memory itself, but to access its value I'll need to declare another variable of the same type without the EEMEM directive: when I read from EEPROM I can use &eememVarName as EEPROM address and the data size is left to me: I should use a eeprom_read_byte for int8_t and uint8_t, eeprom_read_word for int16_t and uint16_t, eeprom_read_dword for int32_t and uint32_t, two calls to eeprom_read_dword and some bit shifting for int64_t and uint64_t, and so forth.

Now, while I see a big advantage in not being limited to read/write one byte at time (which is not strictly related to EEMEM directive usage), I also see the advantage of not being forced to define EEPROM locations upfront: this should somewhat simplify using EEPROM storage in libraries as you automatically avoid conflicts (all the address are computed at compile time): I like it!

Now I need a way to provide defaults so I can flash EEPROM value alongside the firmware. My favorite development environment id Arduino Eclipse, which in turns uses the Arduino toolchain.

How can I prepare an EEPROM file containing the values I want to put into EEPROM using the compiler generated addresses?

in case you are not familiar with Arduino Eclipse, this is the output I get when building a firmware containing an EEMEM directive:

make all 
Building file: ../herba.cpp
Starting C++ compile
"R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avr-g++" -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=155-r2 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR    -I"R:\Tools\ArduinoIDE\hardware\arduino\avr\cores\arduino" -I"R:\Tools\ArduinoIDE\hardware\arduino\avr\variants\eightanaloginputs" -I"R:\Projects\viridi-nexu\common" -I"R:\Arduino\libraries\RF24" -I"R:\Arduino\libraries\LowPower" -I"R:\Tools\ArduinoIDE\libraries\SPI" -I"R:\Tools\ArduinoIDE\libraries\EEPROM" -I"R:\Arduino\libraries\VoltageReference" -I"R:\Arduino\libraries\OneWire" -I"R:\Arduino\libraries\MicroDebug" -MMD -MP -MF"herba.cpp.d" -MT"herba.cpp.d" -D__IN_ECLIPSE__=1 -x c++ "../herba.cpp"  -o  "herba.cpp.o"
Finished building: ../herba.cpp
 
Starting combiner
"R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avr-gcc" -Os -Wl,--gc-sections -mmcu=atmega328p -o "R:/Projects/viridi-nexu/herba/Release/herba.elf"    ./herba.cpp.o  ./common/RF24Address.cpp.o  ./Libraries/VoltageReference/VoltageReference.cpp.o  ./Libraries/SPI/SPI.cpp.o  ./Libraries/RF24/RF24.cpp.o  ./Libraries/OneWire/OneWire.cpp.o  ./Libraries/LowPower/LowPower.cpp.o  ./Libraries/EEPROM/EEPROM.cpp.o  ./Libraries/Battery/Battery.cpp.o   R:/Projects/viridi-nexu/herba/Release/arduino.ar   "R:/Projects/viridi-nexu/herba/Release/arduino.ar" "-LR:/Projects/viridi-nexu/herba/Release" -lm
Finished building: herba.elf
 
Create eeprom image
"R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "R:/Projects/viridi-nexu/herba/Release/herba.elf" "R:/Projects/viridi-nexu/herba/Release/herba.eep"
Finished building: herba.eep
 
Create Flash image (ihex format)
"R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avr-objcopy" -O ihex -R .eeprom "R:/Projects/viridi-nexu/herba/Release/herba.elf" "R:/Projects/viridi-nexu/herba/Release/herba.hex"
Finished building: herba.hex
 
Building target: herba
Printing size:
"R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avr-size" -A "R:/Projects/viridi-nexu/herba/Release/herba.elf"
R:/Projects/viridi-nexu/herba/Release/herba.elf  :
section             size      addr
.data                636   8388864
.text              13546         0
.bss                 242   8389500
.eeprom                4   8454144
.debug_aranges      2744         0
.debug_pubnames     6326         0
.debug_info        51917         0
.debug_abbrev       9927         0
.debug_line        27045         0
.debug_frame        4816         0
.debug_str         13228         0
.debug_loc         28079         0
.debug_ranges       2816         0
Total             161326


Finished building target: herba

The herba.eep file content is somewhat simple:

:02000000CCCC66
:00000001FF

With the following use of EEMEM in the source code

EEMEM uint16_t something = 0xCCCC;

Which seems somewhat correct to me: I'm defining the default value in my code and the compiler is taking it into the .eep file, but when I read that same value using uint16_t another = eeprom_read_word(&something).... I get 0xFFFF :cold_sweat:

How can I push the .eep file onto the EEPROM?

UPDATE

I self answered my own question after a quick search: I can use avrdude to flash the eeprom contents just using

R:/Tools/ArduinoIDE/hardware/tools/avr/bin/avrdude -CR:/Tools/ArduinoIDE/hardware/tools/avr/etc/avrdude.conf -patmega328p -carduino -P COM3 -b57600 -D -Ueeprom:w:R:\Projects\viridi-nexu\herba/Release/herba.eep:i

Now I need to write some code to generate the .eep files: if you guys already have some reference it would be a time saver!