EEprom content declaration data directly from sketch

Hi to everybody, I’d like to know how to define eeprom data content directly into the sketch sourcecode so that during compiling and uploading to my arduino i’ve got the values stored directly to my internal eeprom.

I’ve tried to search into the forum but i’ve found nothing.

I don’t want to do a separate program that upload the eeprom content nor a function that initialize the eeprom in setup() loop.

Thank you in advance to everybody.

Example:
in Microchip PIC assembler I can define;

ORG 0x4100
DATA ‘0x05’, ‘0x0D’, ‘0x33’. ‘0x54’, ‘0x30’ … etc.

Which is the equivalent in Arduino IDE? Is there an alternative or a
directive in AVR or GCC compiler to do what i’m looking for?

P.S.: excuse me for my sluggish english :wink:

Which is the equivalent in Arduino IDE?

EEPROM.write()

You can write data to EEPROM in setup(), if the data of interest does not exist.

nor a function that initialize the eeprom in setup() loop.

Initialising the EEPROM in setup() seems an obvious thing to do. Why don't you want to use that method ?

You can also create a separate sketch that loads the EEPROM, and then load your "real" sketch.

ALL OF THE FOLLOWING ASSUMES AN 8-BIT AVR BOARD - YOU HAVEN'T TOLD US WHAT YOU HAVE!

Although there are viable use cases for this, it isn't something that many people want to do - so the bootloader does not support it (adding support for writing the eeprom to the board would have made it take up 1024 bytes instead of 512). If there's a way to make the compiler generate EEPROM image, I don't know what it is - but you wouldn't be able to upload it without using an ISP programmer even if you could.

So you're left with either uploading EEPROM contents via ISP programmer, or using a "prepare the eeprom" sketch

Not ideal, for sure.

I would probably go the isp programming route (using eXtremeBurnerAVR and a USBAsp - those are my go-to)

It is possible, but if you want to do it with the IDE you need to do some hacks.

Just like avr/pgmspace.h defines the PROGMEM attribute tha tells the compiler to put the values in flash memory, avr/eeprom.h has an EEMEM attribute that puts the values in EEPROM.

#include <avr/eeprom.h>

uint8_t EEMEM radio_address[3] = {0x84, 0xB5, 0x0C};

Those variable pointers can be used as the addresses for the native avrlibc eeprom functions, like eeprom_read_byte, eeprom_read_word, or eeprom_read_block.

The IDE automatically generates a .eep file that contains these EEMEM variables if you define, initialize, and use them. However, it does nothing with this file. A separate avrdude command is needed, but the IDE does not use it.

I’ve been hacking around to make my own boards.txt and platform.txt file that can load EEPROM and even have fuses defined in the sketch. These will be a menu option when selecting a board, just like there’s a processor and speed sub menu when you select a Pro Mini board. I just started a couple days ago so it’s not yet ready for public consumption.

Teaser shot:
screenshot.71.png

Also yes, DrAzzy is right. All of this is assuming you have an AVR based board and have an ISP device you can use to program the chip. An Arduino board running the ArduinoISP sketch can be used as the programmer for another chip, but not for itself.

KeithRB:
You can also create a separate sketch that loads the EEPROM, and then load your "real" sketch.

He doesn't want to do that either.

I await his reasons with interest.

Thank you everybody for your kind reply....

UKHeliBob:
Initialising the EEPROM in setup() seems an obvious thing to do. Why don't you want to use that method ?

Hi UKHeliBob, I don't want to initialize the eeprom data value into setup() because I'm going to loose many bytes of program data and because that operation is useful only for the first boot (in absolute) of the arduino.

In fact once initialized the values they don't need anymore an initialization so I think it is a waste of program space (usegul for other piece of code).

KeithRB:
You can also create a separate sketch that loads the EEPROM, and then load your "real" sketch.

Thank you KeithRB for your suggestion, but i don't want to use this solution because I've got to program an huge number of boards and this solution will take a long time (upload the eeprom data program, turn on arduino for initialization and then reprogram it with the correct sketch)

DrAzzy:
ALL OF THE FOLLOWING ASSUMES AN 8-BIT AVR BOARD - YOU HAVEN'T TOLD US WHAT YOU HAVE!

Excuse me weather I don't have specified the board, but at the moment I don't have got a particular board, but a particular chip!
In fact I'm using ATMEGA 328P on a self constructed board.

I'm programming it via ISP and USBtinyISP programmer in Linux Ubuntu-MATE for ARM, so i don't use any bootloader but direct programming via MISO/MOSI.

Excuse me if i didn't gave you this usefoul information.
MOSI

I've got to program an huge number of boards

In that case I would set up the .hex file (the program) and another .hex file (the EEPROM data) and use avrdude to manually upload both (when I say "manually" I mean in a script).

The program "avrdude" has options to set fuses, upload PROGMEM (program memory) and EEPROM. It could be done quite rapidly.

Thank you for your reply Nick Gammon,

this solution will be my "second choise" if there's no one solution in Areduino IDE.

Thank you everyone for your attention and suggestions.

Jiggy-Ninja:
It is possible, but if you want to do it with the IDE you need to do some hacks.

Just like avr/pgmspace.h defines the PROGMEM attribute tha tells the compiler to put the values in flash memory, avr/eeprom.h has an EEMEM attribute that puts the values in EEPROM.

#include <avr/eeprom.h>

uint8_t EEMEM radio_address[3] = {0x84, 0xB5, 0x0C};




...

I've been hacking around to make my own boards.txt and platform.txt file that can load EEPROM and even have fuses defined in the sketch. These will be a menu option when selecting a board, just like there's a processor and speed sub menu when you select a Pro Mini board. I just started a couple days ago so it's not yet ready for public consumption.

Hey Jiggy-Ninja, This solution seems to be very nice…

If you want I can help you with beta testing.

This might be of interest to Jiggy-Ninja and Paolaner: Add support to use AVR dude to upload .eep files on sketch upload by fulda1 · Pull Request #4963 · arduino/Arduino · GitHub

Paolaner:
Hi to everybody, I'd like to know how to define eeprom data content directly into the sketch sourcecode so that during compiling and uploading to my arduino i've got the values stored directly to my internal eeprom.

I've tried to search into the forum but i've found nothing.

I don't want to do a separate program that upload the eeprom content nor a function that initialize the eeprom in setup() loop.

Thank you in advance to everybody.

Example:
in Microchip PIC assembler I can define;

ORG 0x4100
DATA '0x05', '0x0D', '0x33'. '0x54', '0x30' .... etc.

Which is the equivalent in Arduino IDE? Is there an alternative or a
directive in AVR or GCC compiler to do what i'm looking for?

P.S.: excuse me for my sluggish english :wink:

Same as if you were defining something in PROGMEM... but instead use the keyword EEMEM.

Note that some bootloaders will not "burn" your data into the EEPROM, even if you've declared it (some bootloader code has the EEPROM support removed to keep the size down).

i keep a 1-byte 'signature' in eeprom along with the data.

Then during setup, i check if the signature is the same as expected for the current version of code (may be revised since eeprom format was last written), then if the same - continue on unchanged as normal.... otherwise head off and rewrite the eeprom with the new defaults or data moved from the 'old' locations.

UKHeliBob:
He doesn't want to do that either.

I await his reasons with interest.

There are reasons for wanting to load EEPROM directly at upload time... like this for example:

// Sony camera shutter release code 0x000B4B8F (focus and shoot)
// Header + 20 bit (5 byte) command.
// high bit (0x8000) set = LED on
static const uint16_t shutter1[] EEMEM = {
    // header
    0x8060, 0x0018,
    // data
    0x8030, 0x0018, 0x8018, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, // B
    0x8018, 0x0018, 0x8030, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, // 4
    0x8030, 0x0018, 0x8018, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, // B
    0x8030, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, // 8
    0x8030, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, 0x8030, 0x01c8, // F
    0x0000,
};

If the designers of the Arduino system (especially the IDE) didn't go out of their way to dumb down C++ to reach the lowest common denominator, we wouldn't have most of the problems that we have.

We are up to version 1.6.12 and STILL there's no "Preferences" option to enable or disable floating point support.

We are up to version 1.6.12 and STILL there's no way to easily use plain old printf... people still need to build up output lines a piece at a time.

But, we have the INCREDIBLY USEFUL ability to convert the PDE extension to INO, as well as checking for updates at startup.... ad-nauseaum.

Users are encouraged to use the EEPROM library and EEPROM memory as discrete locations (thereby forcing them to remember how many bytes their variable uses and where the next var should go) rather than using EEMEM like it's supposed to be.

We have people who care how many extra nanoseconds "doing it right" will take. Sheesh... if that bothers you than stick in a faster crystal (or use a Core i7 processor instead).

This is why anyone who actually needs to get something working right ditches the IDE and uses a plain old text editor and a Makefile.........

(sorry I just had to......rant mode off)

The IDE is there to teach the basics. Once you move on to advanced concepts you should move to a more advanced IDE. They could make the Arduino IDE more advanced but that would make it harder for the target audience of newbies to learn to use.

I see these kind of rants a lot and I just think why are you still on a tricycle if you are up to the BMX level? Why is it that people just can't let go of the simple noob IDE and move on once they know what they're doing? Why sit there on a tricycle bitching about how hard it is to ride on the BMX track when there are new bicycles for free all over the place?

If the designers of the Arduino system (especially the IDE) didn't go out of their way to dumb down C++ to reach the lowest common denominator, we wouldn't have most of the problems that we have.

Maybe not, but we would have different ones instead.

Krupski:
There are reasons for wanting to load EEPROM directly at upload time... like this for example:

// Sony camera shutter release code 0x000B4B8F (focus and shoot)

// Header + 20 bit (5 byte) command.
// high bit (0x8000) set = LED on
static const uint16_t shutter1 EEMEM = {
    // header
    0x8060, 0x0018,
    // data
    0x8030, 0x0018, 0x8018, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, // B
    0x8018, 0x0018, 0x8030, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, // 4
    0x8030, 0x0018, 0x8018, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, // B
    0x8030, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, 0x8018, 0x0018, // 8
    0x8030, 0x0018, 0x8030, 0x0018, 0x8030, 0x0018, 0x8030, 0x01c8, // F
    0x0000,
};

Is that really something that needs to be changeable by the application software? Seems like it's more appropriate for PROGMEM.

If the designers of the Arduino system (especially the IDE) didn't go out of their way to dumb down C++ to reach the lowest common denominator, we wouldn't have most of the problems that we have.

So far, the only thing I've seen in the AVR core that I actually consider to be really stupid is the decision to mask out all but the lower 3 bits of the channel number from the analogRead input. That makes it impossible to set the bandgap reference (channel 14) as an input, even if you try and be smart and do analogRead(0xE + A0) to get around the subtraction it does.

printf may be one thing, but even if you don't disable FP in the compiler, if you don't use anything FP the linker should throw it all out. The only use for that option then would be to alert you that you've inadvertently used FP.

Users are encouraged to use the EEPROM library and EEPROM memory as discrete locations (thereby forcing them to remember how many bytes their variable uses and where the next var should go) rather than using EEMEM like it's supposed to be.

I did it like this:

// ***************************************************
// EEPROM indexes and pointers
// ***************************************************
// Ring counter method from Atmel App Note 101
// High Endurance EEPROM Storage
#define EEPROM_START_ADDRESS 10
const uint8_t max_EEPROM_items = 150;
int16_t ring_index = 0;
uint8_t ring_counter;

uint8_t* status_buffer = (uint8_t*) EEPROM_START_ADDRESS;
config_t* parameter_buffer = (config_t*) (status_buffer + (sizeof(status_buffer[0])*max_EEPROM_items));

I converted them to pointers to use the avr/eeprom functions, but the basic idea is still the same: use the compiler to generate the EEPROM addresses using sizeof and the number of items I wanted in the array.

We have people who care how many extra nanoseconds "doing it right" will take. Sheesh... if that bothers you than stick in a faster crystal (or use a Core i7 processor instead).

I'm pretty sure none of the AVRs can even go much faster. I think they all max out at 20 MHz. I think the tiny85 (and maybe some others) can be clocked off the internal frequency multiplier, but then you only have 5 GPIO to work with. You'd need to bump up to an ARM chip or an ESP to have an appreciable speed boost.

Krupski:
If the designers of the Arduino system (especially the IDE) didn't go out of their way to dumb down C++ to reach the lowest common denominator, we wouldn't have most of the problems that we have.

Yes, but, if Optiboot supported EEPROM programming it would be larger as someone pointed out earlier. There is a way of pre-uploading EEPROM data as I mentioned.

I have a “personalized” (i.e. hacked) version of Optiboot that uses 508 bytes and supports EEPROM programming and verification. :slight_smile: