Hmm, it seems that my initial enthusiasm was somewhat premature... It seems to work fine, until I declare an array in EEMEM, at which point the whole eeprom writing stage fails. I could use an extra pair of eyes...
Index: AvrdudeUploader.java
===================================================================
--- AvrdudeUploader.java (revision 453)
+++ AvrdudeUploader.java (working copy)
@@ -44,6 +44,7 @@
} else {
Collection params = getProgrammerCommands(Preferences.get("upload.using"));
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
+ params.add("-Ueeprom:w:" + buildPath + File.separator + className + ".eep:i");
return avrdude(params);
}
}
@@ -62,6 +63,7 @@
"-b" + Preferences.getInteger("boards." + Preferences.get("board") + ".upload.speed"));
commandDownloader.add("-D"); // don't erase
commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
+ commandDownloader.add("-Ueeprom:w:" + buildPath + File.separator + className + ".eep:i");
if (Preferences.get("boards." + Preferences.get("board") + ".upload.disable_flushing") == null ||
Preferences.getBoolean("boards." + Preferences.get("board") + ".upload.disable_flushing") == false) {
Index: Compiler.java
===================================================================
--- Compiler.java (revision 453)
+++ Compiler.java (working copy)
@@ -211,16 +211,20 @@
List commandObjcopy;
commandObjcopy = new ArrayList(baseCommandObjcopy);
- commandObjcopy.add(2, "srec");
+ commandObjcopy.add(2, "ihex");
+ commandObjcopy.set(3, "-j");
commandObjcopy.add(".eeprom");
+ commandObjcopy.add("--set-section-flags=.eeprom=alloc,load");
+ commandObjcopy.add("--change-section-lma");
+ commandObjcopy.add(".eeprom=0");
commandObjcopy.add(buildPath + File.separator + sketch.name + ".elf");
- commandObjcopy.add(buildPath + File.separator + sketch.name + ".rom");
+ commandObjcopy.add(buildPath + File.separator + sketch.name + ".eep");
if (execAsynchronously(commandObjcopy) != 0)
return false;
commandObjcopy = new ArrayList(baseCommandObjcopy);
commandObjcopy.add(2, "ihex");
- commandObjcopy.add(".flash");
+ commandObjcopy.add(".eeprom");
commandObjcopy.add(buildPath + File.separator + sketch.name + ".elf");
commandObjcopy.add(buildPath + File.separator + sketch.name + ".hex");
if (execAsynchronously(commandObjcopy) != 0)
The patch above changes the following:
- Compiler.java is changed so it creates an .eep file in ihex format, instead of a .rom file in srec format
- Compiler.java is changed so the .hex file does not contain the eeprom section
- AvrdudeUploader.java is changed so it also uploads the .eep file to eeprom space
You can use this sketch to test the modifications:
#include <avr/eeprom.h>
byte EEMEM NonVolatileChar = 123;
int EEMEM NonVolatileInt = 12345;
//char EEMEM NonVolatileString[15]; = "Hello world";
void setup() {
char SRAMchar;
int SRAMint;
char SRAMstring[15];
SRAMchar = eeprom_read_byte(&NonVolatileChar);
SRAMint = eeprom_read_word(&NonVolatileInt);
//eeprom_read_block((void*)&SRAMstring, (const void*)&NonVolatileString, 15);
Serial.begin(9600);
Serial.println(SRAMchar,DEC);
Serial.println(SRAMint,DEC);
Serial.println(SRAMstring);
}
void loop() {
}
When used like this, the code works fine; The NonVolatileChar and NonVolatileInt are read as expected. Uncommenting the EEMEM declaration of NonVolatileString breaks the eeprom upload process for me, and not even the NonVolatileChar and NonVolatileInt read back correctly anymore. This is the same with both the IDE changes in this post and the makefile changes I posted before, though the makefile by default does not verify the written data.
Update: To my untrained eye, it looks like the bootloader is putting bytes in the wrong places in the eeprom section. Something about byte vs word boundaries and/or big vs little endian-ness. The bootloader is special-casing the Atmega 168 when it comes to writing the eeprom section, and I don't understand that code. I'll have to build me an AVR ISP so I can see what exactly gets put in the eeprom, and to see if it works if I use the AVR ISP instead of the bootloader.