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 whenfoo
isuint8_t*
versusuint32_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 calledeeprom_index
instead of a pointer type, IMHO.