Avrdude and eeprom?

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

O've been happily programming my aeduino uno using the bat file

@rem file avrdudecom12.bat Mar 9 13 Bob G for oled12832
avrdude -c arduino -P com12 -b 115200 -p ATmega328P -e -U flash:w:oled12832.hex
pause

Now I want to program the eeprom too, so I changed it to this

avrdude -c arduino -P com12 -b 115200 -p ATmega328P -e -U flash:w:oled12832.hex -U eeprom:w:oled12832.eep
pause

And it says verify error loc 0 not eq 0x08. Crap. Never had this problem with atmel programmers and sw. Am I trying to burn the eep file wrong?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are using the standard Arduino bootloader... it does not support EEPROM.

I have a stk500v1 boot loader which does so. I have been planning to publish it for a while, but haven't gotten ' a round to-it ' yet. Let me know if you want the source.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So none of these arduino programs start out with stuff loaded into eeprom? Nutty. Thanks for telling me.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So none of these arduino programs start out with stuff loaded into eeprom?

Presumably you can always do it programmatically?

setup() {
 if (eeprom.read(0) != 0xAA) {
   eeprom.write(1) = 12;
   eeprom.write(2) = 34;
   eeprom.write(0) = 0xAA;
 }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The older Arduino bootloaders handle EEPROM.

The current UNO boards use Optiboot which does NOT handle EEPROM.

Optiboot fits into only 256 words and consequently is more appealing to the Arduino community. i.e. 32256 bytes available for sketches.

Personally, I would have thought it wise to tweak Optiboot in ASM so that it does flash and eeprom correctly.

Most Arduino sketches don't use pre-loaded EEPROM. As Cliff says, you can initialise it in your setup().

You only encounter the 'feature' when you use the bootloader for non-Arduino programs. (as I do)

There are too many UNOs out in the world. If you 'updated' Optiboot it would seriously upset all the pre-existing UNO owners.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll try the init suggestion.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'll try the init suggestion.

To be honest I'm never a fan of things like:

   EEPROM.write(1) = 12;
   EEPROM.write(2) = 34;
   EEPROM.write(0) = 0xAA;

with hard-coded addresses. Suppose I make a mistake and only allow 1 byte at location 1 (written with 12 above) when I really meant it to hold an int. Also how do I even write an int if EEPROM.write() only takes a byte parameter.

I was going to suggest deriving a class from EEPROMClass with overloaded .write and .read methods for various width types. But maybe just as good(better?) a solution is the Templates solution presented here:

http://playground.arduino.cc/Cod...

but that still has the user positioning items in EEPROM instead of letting the intelligent linker do it. I think I'd use it with:

#include 
#include "EEPROMAnything.h"
#include 

int n EEMEM;
char text[10] EEMEM;

then code such as:

EEPROM_writeAnything(&n, 12345);
EEPROM_writeAnything(&text, "hello");

The linker will position 'n' and 'text' in EEPROM for you (I guess n may be at bytes 0,1 and text at byte 2..12 but that's left up to the linker).

On the other hand you could just use GCCs original:

#include 

int n EEMEM;
char text[10] EEMEM;

setup() {
  eeprom_write_word(&n, 12345);
  eeprom_wite_block((const void *)&text, "hello", sizeof(text));
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have no problems with hard-coded EEPROM locations.
After all, you probably want to preserve your 'data' over several builds and even platforms.
e.g. you often want your engine data, telephone numbers or nuclear codes to work on a different CPU or use another compiler.

IMHO, you either let the linker do everything or keep control yourself. Mixing the two is asking for trouble.

OTOH, if your masterpiece is never going to change, it really does not matter.

Incidentally, I am a recent convert to C++. It is so simple to extend an existing class. So you create a new class that inherits all the features of the original class. And if you don't like an existing method, you can replace it with your improved version:

#include 

class EEPROM_extended : public EEPROM {
   public:
      uint16_t read_word(uint16_t address);  // extend
      uint8_t read(uint16_t address);        // replace
};

Untested. I am still learning.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

After all, you probably want to preserve your 'data' over several builds and even platforms.

Then you use a struct{}.
Quote:

Untested. I am still learning.

The base class () is actually called EEPROMClass so derive from ": public EEPROMClass" rather than just ": public EEPROM". But also note that you probably want overloaded versions for all stdint.h types as well as float, double and so on. This is why I said the template solution I linked to may be "better" because one piece of code fits all.

It took me a bit of time to get my head around templates (I'm still learning) but they are a bit like a "super macro" and each invocation just replaces the T (type) with the type of the passed object. So rather than the over-loaded solution:

void write(uint16_t n) {
  write((uint8_t) n & 0xFF);
  write((uint8_t) n >> 8);
}

void write(uint32_t n) {
  write((uint8_t) n & 0xFF);
  write((uint8_t) n >> 8);
  write((uint8_t) n >> 16);
  write((uint8_t) n >> 24);
}
..

and all the other over-loaded versions of the write (or read) method you just have their single:

template  int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
          EEPROM.write(ee++, *p++);
    return i;
}

and when called with EEPROM_writeAnything(7, (uint16_t) 1234); so T=uint16_t the for() loop writes 2 bytes while when called with EEPROM_writeAnything(7, (uint32_t) 0xDEADBEEF); so T=uint32_t the same code writes 4 bytes and so on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I took a class once back in the last millenium. My c compiler has macros to read and write any size var to eeprom. Why should I have thought that I could actually load the eeprom?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Classy response, Bob! :)