Go Down

Topic: Trouble reading/writing EEPROM via avrdude (Read 2044 times) previous topic - next topic

hichhiker

Ok, I have Mega2560's that I need to read and eventually write EEPROM from a computer - which seems to be a perfect job for avrdude, which supports this exact case, however I am getting some very strange results from AVRDude. Short of it, I can read/write EEPROM inside my sketches without any problems, but reading from avrdude gets me some corrupt data. To test this, I wrote a very simple sketch that wipes clean EEPROM, writes some test data and then dumps it to serial in a hexdump-like fashion:

Code: [Select]

#include <EEPROM.h>

void eepromDump() {
  char buff[8];
  int counter = 0;
  byte data = 0;
  Serial.write("EEPROM contents:\n");
  for (int i = 0; i < 4096 ; i++) {
    counter = counter % 16;
    if (counter == 0) {
      snprintf(buff, 10, "%07X", i);
      if (i != 0) {
        Serial.println();
      }
      Serial.print(buff);
    }
    data =  EEPROM.read(i);
    snprintf(buff, 4, " %02X", data);
    Serial.print(buff);
    counter ++;
  }
  Serial.println();
}

void eepromErase(int start){
  Serial.println("Erasing EEPROM");
  for (int addr=start; addr <4096; addr++){ EEPROM.update(addr, 0x00); }
}

void setup() {
  Serial.begin(115200L);
  const char data[63]="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
  EEPROM.put(0, data);
  eepromErase(64);
  eepromDump();
}

void loop() {
}


This does exactly what it should and gives me back something like:
Code: [Select]

Erasing EEPROM
EEPROM contents:
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 66
0000010 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76
0000020 77 78 79 7A 41 42 43 44 45 46 47 48 49 4A 4B 4C
0000030 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 00 00
0000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...<rest are 00's>


So far so good. Now I dump same data using avrdude and dump it out:

Code: [Select]

$ avrdude  -patmega2560 -cwiring -P /dev/cu.usbmodem1421 -b115200 -D -Ueeprom:r:eeprom.raw:r
...<no error output skipped>...
$ hexdump -C eeprom.raw
00000000  30 31 32 33 34 35 36 37  67 68 69 6a 6b 6c 6d 6e  |01234567ghijklmn|
00000010  77 78 79 7a 41 42 43 44  4d 4e 4f 50 51 52 53 54  |wxyzABCDMNOPQRST|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000800  30 31 32 33 34 35 36 37  67 68 69 6a 6b 6c 6d 6e  |01234567ghijklmn|
00000810  77 78 79 7a 41 42 43 44  4d 4e 4f 50 51 52 53 54  |wxyzABCDMNOPQRST|
00000820  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001000


As you see, this is where things got weird. I am getting every other 8 bytes of data.... and they repeat

Now, I am aware that Optiboot cannot handle EEPROM, but I made sure  I am not running it. I am running the standard bootloader, but just to be sure, I re-burned the bootloader using this: https://github.com/nickgammon/arduino_sketches/tree/master/Atmega_Board_Programmer

What am I missing here?

Thanks,

-HH

DrAzzy

Somewhere along the line it looks like it's losing the high bit in the address, so you get halfway through and it starts reading from the start again... Does it happen if you use an ICSP programmer instead of doing it through the bootloader? I would not be surprised if the bootloader has a bug around here - it doesn't jump out at me looking at the code, but like, the EEPROM write section (though not the read section) has a comment indicating that it wasn't tested by the author.


(also - an "empty" EEPROM cell is 0xFF, not 0x00 - if you do a chip erase, they start out with all 1's, not all 0's - same as flash)
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

hichhiker

Somewhere along the line it looks like it's losing the high bit in the address, so you get halfway through and it starts reading from the start again... Does it happen if you use an ICSP programmer instead of doing it through the bootloader? I would not be surprised if the bootloader has a bug around here - it doesn't jump out at me looking at the code, but like, the EEPROM write section (though not the read section) has a comment indicating that it wasn't tested by the author.
That is an interesting thought about bit loss, looks like I may need to look at the bootloader as I really doubt it is in avrdude. It almost seems like a signed/unsigned issue... I need to sit down and work out what is happening, but the off-by-8 sure does seems like a bit is lost when selecting address...

I do not think it has anything to do with the sketch or EEPROM lib, as that stuff is working just fine. I can read/write EEPROM from code and it works exactly as expected. I included that sketch just to demonstrate that I am forcing the EEPROM to a known state before testing reading via avrdude/bootloader, and that the result from avrdude is not correct.

(also - an "empty" EEPROM cell is 0xFF, not 0x00 - if you do a chip erase, they start out with all 1's, not all 0's - same as flash)
If you look at the code, I am manually forcing the entire unused EEPROM space to be 0's - mostly to make sure it is in a known good state for testing. I am not using chip erase for this.

Thanks,

-M

DrAzzy

#3
Jun 30, 2017, 07:55 pm Last Edit: Jun 30, 2017, 07:56 pm by DrAzzy
I agree with your conclusions (except the signed/unsigned part, since you're using bytes and ints, not some 12-bit signed datatype) - BUT as a sanity check, I would really recommend reading the EEPROM with an ISP programmer, to verify that the problem is in the bootloader.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

hichhiker

I agree with your conclusions (except the signed/unsigned part, since you're using bytes and ints, not some 12-bit signed datatype) - BUT as a sanity check, I would really recommend reading the EEPROM with an ISP programmer, to verify that the problem is in the bootloader.
Yes, I need to find a 100mF cap to make my "Arduino As ISP" work because for whatever reason I cannot get Dragon to work properly under OSX :-( But I think checking via ISP is the way to go. Thanks

-HH

DrAzzy

#5
Jun 30, 2017, 11:54 pm Last Edit: Jun 30, 2017, 11:58 pm by DrAzzy
https://www.ebay.com/sch/i.html?_nkw=USBAsp
Cheap and works. Put the PeterVH/bperrypap f/w on it for best results.

Also for the cap (though I have no idea what you mean by 100mF - 100 milli-farads?  (microfarads is probably what you were thinking, which is abbreviated uF) - for disabling reset on Arduino as ISP it's normally recommended to use 10uF cap, but anything within an order of magnitude of that value will work):
https://www.ebay.com/sch/i.html?_nkw=capacitor+kit
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

hichhiker

https://www.ebay.com/sch/i.html?_nkw=USBAsp
Cheap and works. Put the PeterVH/bperrypap f/w on it for best results.
How did I not know about this?!?!? That's awesome - buying a bunch ( A complete random question - you seem like you may know - any idea if there are similar JTAG debuggers that work with Arduino AND OSX? this is whole reason I bought AVRDragon, and it has been pretty useless under OSX)

Also for the cap (though I have no idea what you mean by 100mF - 100 milli-farads?  (microfarads is probably what you were thinking, which is abbreviated uF) - for disabling reset on Arduino as ISP it's normally recommended to use 10uF cap, but anything within an order of magnitude of that value will work):
https://www.ebay.com/sch/i.html?_nkw=capacitor+kit
I actually meant to type "nF". 100nF is what is recommended by the instructable here - but I suspect you are right, it does not need to be exact.. I should have some somewhere.... but I need to find them... usbisp seems like a great simple alternative solution though :-)

Thank you!


-HH

hichhiker

Ok, just tried with AVRDragon (got it to work under mac for ISP) and read the EEPROM - it came out perfect.

There seems to be some weird issue with the bootloader or its interaction with avrdude where address bit 3 is ignored  so that, for example address  0x0060 (0110 0000)  becomes 0x0030 (0011 0000) and 0x0010  (0001 0000) Becomes 0x0008 (0000 1000) :-( I cannot even imagine how this is possible - I could get the sign bit being dropped in some signed/unsigned bug - but a bit in the MIDDLE of the address?? I am off to see if I can track down the bootloader source to look at it...

-HH




demkat1

Ok, just tried with AVRDragon (got it to work under mac for ISP) and read the EEPROM - it came out perfect.

.. for example address   ..(0110 0000)  becomes ... (0011 0000) and ..  (0001 0000) Becomes (0000 1000)
-HH




its a 1bit shift to the right, isnt it?

hichhiker

its a 1bit shift to the right, isnt it?
Not exactly, it is dropping bit 3 and shifting everything left of it. I suppose I made poor examples, but here is another one:

0x0067 (0110 0111)  becomes 0x0037 (0011 0111)

Where green bits are unmolested, red bit is dropped, and blue bits are shifted...

I have tested this on several boards with same results - I am wondering if anyone else would be willing to try this out on their Mega2560 to see if anyone else can replicate this. Maybe something is wrong with my machine. This makes no sense

-HH

DrAzzy

Not as insane as it sounds, as the eeprom is structured with 8 byte pages... but does this match what you posted above? With the hex dump? It doesn't seem to...
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

hichhiker

Not as insane as it sounds, as the eeprom is structured with 8 byte pages... but does this match what you posted above? With the hex dump? It doesn't seem to...
I derived the assumptions based on the output, so if it does not match I did something wrong...

Assuming in EEPROM all the bytes are in order, what I get when I read are bytes 0-7, 16-23, 32-39, and so on. It looks to me as if every other 8 bytes are dropped and when we get to the end at 0x0800 instead of 0x1000, we start over.

At what point does page address gets extracted from EEPROM address? Seems like there may be an extra shift there... I did not see this in bootloader code, but I was not looking that carefully...

The only thing that I can think of is that I am using bootloader that came built-in to the Nick Gammon's programmer sketch - and I am not 100% sure what it was build with or from.... (That said, it is about the most trustworthy source I can think of...)

-HH

demkat1

I admit I do not know about avrdude.
I would try writing data through arduino IDE and read trough avrdude and then the opposite.
Sorry if I miss something

hichhiker

I admit I do not know about avrdude.
I would try writing data through arduino IDE and read trough avrdude and then the opposite.
Sorry if I miss something
Arduino IDE just uses avrdude - so it should be same thing.

I have raised the debug level on avrdude to see exactly what is being sent

Code: [Select]

avrdude: Send: . [1b] . [14] . [00] . [04] . [0e] . [16] . [00] . [08] . [a0] . [bb]
avrdude: Recv: . [1b]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [0b]
avrdude: Recv: . [0e]
avrdude: Recv: . [16]
avrdude: Recv: . [00]
avrdude: Recv: 0 [30]
avrdude: Recv: 1 [31]
avrdude: Recv: 2 [32]
avrdude: Recv: 3 [33]
avrdude: Recv: 4 [34]
avrdude: Recv: 5 [35]
avrdude: Recv: 6 [36]
avrdude: Recv: 7 [37]
avrdude: Recv: . [00]
avrdude: Recv: . [1c]
avrdude: Send: . [1b] . [15] . [00] . [05] . [0e] . [06] . [00] . [00] . [00] . [08] . [0b]
avrdude: Recv: . [1b]
avrdude: Recv: . [15]
avrdude: Recv: . [00]
avrdude: Recv: . [02]
avrdude: Recv: . [0e]
avrdude: Recv: . [06]
avrdude: Recv: . [00]
avrdude: Recv: . [04]
avrdude: Send: . [1b] . [16] . [00] . [04] . [0e] . [16] . [00] . [08] . [a0] . [b9]
avrdude: Recv: . [1b]
avrdude: Recv: . [16]
avrdude: Recv: . [00]
avrdude: Recv: . [0b]
avrdude: Recv: . [0e]
avrdude: Recv: . [16]
avrdude: Recv: . [00]
avrdude: Recv: g [67]
avrdude: Recv: h [68]
avrdude: Recv: i [69]
avrdude: Recv: j [6a]
avrdude: Recv: k [6b]
avrdude: Recv: l [6c]
avrdude: Recv: m [6d]
avrdude: Recv: n [6e]
avrdude: Recv: . [00]
avrdude: Recv: . [16]
avrdude: Send: . [1b] . [17] . [00] . [05] . [0e] . [06] . [00] . [00] . [00] . [10] . [11]
avrdude: Recv: . [1b]
avrdude: Recv: . [17]
avrdude: Recv: . [00]
avrdude: Recv: . [02]
avrdude: Recv: . [0e]
avrdude: Recv: . [06]
avrdude: Recv: . [00]
avrdude: Recv: . [06]


Of course now I need to go learn the stk500v2 protocol to decode it :-(

The odd bit is that read flash and read eeprom are almost same, but this issue is very specific to eeprom...


demkat1

 ok, i know that arduino ide uses avrdude, but thats all.

Anyway, i believe that the writer of the "addressing system" (bootloader or whatever) uses the same "procedure" in reading as in writing and erasing. So, if for any reason the user wants to access a specific address and the system is not translating the address value correctly, it will go to the SAME ERROR "cell" for any operation.
So, with the same system for reading and writing there should be no obvious problem even though there would be completely different actual" mapping.

But in above "printout"
avrdude: Send: . [1b] . [14] . [00] . [04] . [0e] . [16] . [00] . [08] . [a0] . [bb]
avrdude: Recv: . [1b]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [0b]
avrdude: Recv: . [0e]
avrdude: Recv: . [16]
avrdude: Recv: . [00]
avrdude: Recv: 0 [30]  and so on

it is obvious that they differ.
I think I cannot help here.

Go Up