Electronic – Pointer Size using eeprom.h with ATmega328p in AVR-GCC

atmegaavravr-gcceepromprogramming

I am working on a project that randomly reads and writes large blocks of data from EEPROM, based on user input. I have used the EEPROM before, but I never really thought about this. In the operations described in the standard eeprom.h file (documentation), you always have to add a typecast to a known address location. For example:

DATA_BYTE = eeprom_read_byte((uint8_t*)LOCATION);

This makes sense, but what i don't understand is its use for larger data, such as the following:

DATA_DWORD = eeprom_read_dword((uint32_t*)LOCATION);

Is the typecast (unit32_t) describing the pointer size, or the size of data being pointed to? I know the ATmega328p has 1kBytes of EEPROM, meaning it would take a 16 bit pointer to hold the address to a single data byte. So I'm guessing this means the typecast has nothing to do with the pointer size, but the size of the data being written/read… I know it works, I would just like to understand it better.

I hope that makes sense. Thanks in advance!

Best Answer

In AVR, Pointers to regular memory (SRAM) are 16-bit. But EEPROM is not regular memory. The eeprom.h in AVR Libc takes pointers to different data types, depending on what you actually write to EEPROM: when you read/write a byte, it takes a byte pointer, when you read/write a word it takes a word pointer, etc. Hence the difference in the different functions you quote. And you are right: the pointers themselves are the same size, just the size of what they "point to" is different. You can verify this for yourself by checking what sizeof(foo) returns when foo is uint8_t* versus uint32_t*.

But, in fact, the arguments you pass to AVR Libc eeprom functions are not really pointers in the regular sense of the word: you cannot access the data they "point to" except via the EEPROM functions. It might have been clearer if the AVR Libc EEPROM functions took a uint16_t type called eeprom_index instead of a pointer type, IMHO.