Tero Sinervo wrote:
David Brown wrote:
It does not matter what addresses are used for ram variables, nor for
the flash code that is updated. But very often it /does/ matter for
persistent data, and it is certainly important for pre-defined memory
maps such as for external peripherals (there is a good reason why
internal peripherals are not defined in a file with lines like
"volatile uint8_t PORTD" !). The only way to be entirely sure that an
object is allocated to the same address each time is for it to be the
only thing in a section, and the section is given an explicit address
at link time. When you are talking about data that can't be addressed
directly in C on the AVR anyway, why bother with that?
Yes, very often but not always. Consider having text strings in pgmspace
but running out of space. Good thing you have a mass storage and file
system - you can move the text strings to an external section and load
the section to a file. Only thing you need to do is write a driver that
replaces pgmspace string stuff with file access. It doesn't matter in
which order the strings are in the file.
That's a good example, and in general if the external data is updated
with the software, then there is no need to be consistent about the
addresses. In that case an external section can do the job.
But you want to be very sure that the external data /is/ consistent -
I've worked with systems where the text strings were in an external
eeprom, which should have been updated with the software. Since (by
mistake) they were not updated, test systems started showing messages in
the wrong language...
I often find that when you want to generate data for external memory
like this, a C compiler is not the best tool for the job in the first place.
Note that you /can/ (and should) get the compiler to do most of the
effort in the allocation. The easiest way is to make a struct type
for all your eeprom data:
typedef struct { uint16_t moneyLeft; uint16_t runTimeSeconds; }
eepromData;
Then you can access this data with something like:
eeprom_read_word((uint16_t*) (baseAddress +
offsetof(eepromData, runTimeSeconds)));
You manually specify a base address, and let the compiler handle the
rest.
This is all all right although perhaps offsetof is redundant:
eepromData* eeprom = BASEADDRESS;
eeprom_read_word(&eeprom->runTimeSeconds);
Yes, that's a neater way to write it in this case. Writing the sums
manually (with offsetof) is perhaps easier to adapt to 32-bit addresses
for an external 4 MB flash, and also possibly easier to relocate to
different base addresses. It all gets buried away in accessor functions
or macros, so you should write whatever way you think is clearest.
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list