Black Lives Matter - Action and Equality. ... Adafruit joins the Stop Hate for Profit campaign.
0

Reading/writing the eeprom section with the bootloader
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Reading/writing the eeprom section with the bootloader

by ahoeben on Fri May 23, 2008 7:09 am

While investigating the use of the EEMEM directive in Arduino skecthes, I found a bug in the ATMegaBoot bootloader that makes reading from/writing to the eeprom section impossible.

This can be checked fairly easily by just trying to write an ihex file to eeprom; the verification stage will fail (unless you write fewer than 3 bytes).

The patch below seems to fix the bootloader for the atmega168, but I don't have enough avr knowledge to see if I it works in all cases and/or does not break stuff with other atmega types.
Code: Select all | TOGGLE FULL SIZE
Index: ATmegaBOOT_168.c
===================================================================
--- ATmegaBOOT_168.c   (revision 453)
+++ ATmegaBOOT_168.c   (working copy)
@@ -482,6 +482,7 @@
      }
      if (getch() == ' ') {
        if (flags.eeprom) {                //Write to EEPROM one byte at a time
+          address.word = address.word << 1;        //address * 2 -> byte location
         for(w=0;w<length.word;w++) {
 #ifdef __AVR_ATmega168__
           while(EECR & (1<<EEPE));
@@ -627,11 +628,10 @@
      if (address.word>0x7FFF) flags.rampz = 1;      // No go with m256, FIXME
      else flags.rampz = 0;
 #endif
+       address.word = address.word << 1;        // address * 2 -> byte location
      if (getch() == 'E') flags.eeprom = 1;
-       else {
-      flags.eeprom = 0;
-      address.word = address.word << 1;        // address * 2 -> byte location
-       }
+       else flags.eeprom = 0;
+
      if (getch() == ' ') {                // Command terminator
        putch(0x14);
        for (w=0;w < length.word;w++) {           // Can handle odd and even lengths okay
 


Understandably, Mellis is not in a hurry to implement an official fix; current Arduinos need to be reflashed using some sort of ISP to fix this bug, and the use cases where the bug manifests are very limited (basically only when using the EEMEM directive, which does not currently work anyway).

But I figured that perhaps a fix for this issue could find its way into ADAboot...

PS: the EEMEM directive is used to allocate variable space in eeprom memory. It works similarly to PROGMEM, which allows you to store (static) variable values in flash instead of RAM. The EEMEM directive would be great for storing persistent 'settings' variables in eeprom.

ahoeben
 
Posts: 21
Joined: Fri Apr 25, 2008 3:18 pm

by adafruit on Fri May 23, 2008 12:00 pm

thanks for the tip! i looked at the eemem stuff once and remember thinking "this dont look right" :)

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm
Location: nyc

by ahoeben on Fri May 23, 2008 1:23 pm

ladyada wrote:... and remember thinking "this dont look right" :)


I'm not sure it's going to necessarily look better with my changes in, I just poked at the code untill it worked ;-)

If you're going to look in to the eeprom code, you may also want to look at the atmega168-specific eeprom writing workaround in the code. There's a comment that says that avr-libc does not support the atmega168 for eeprom writing, but it seemed that it did in fact work with the current (newer) version of the library. However, the workaround results in a smaller binary, so it may still be preferable.

ahoeben
 
Posts: 21
Joined: Fri Apr 25, 2008 3:18 pm

Please be positive and constructive with your questions and comments.