Reputation: 701
In an embedded C++ context, I have defined a separate linker section in flash memory, far away from the rest of the code/data, in which I store data that the user may modify at runtime. (EEPROM emulation, basically)
I also have a custom device firmware updater, that's going to overwrite the read-only code/data in flash, except this section (and that of the firmware updater), because I want the persistent configuration changes the user has made to persist, even if they perform a firmware update.
As part of these firmware, I may extend the amount of configuration the user can do. So, I have one code file that's essentially a list of global variables, that's getting linked at a given position in flash, and would be adding lines at the end. Of course, I really want to ensure that the position in memory of the variables that were here before don't change.
What am I guaranteed about this ? Going by Memory layout of globals, I'm not sure I'm guaranteed that sequentially adding lines at the end of the file wouldn't alter the position of the previous variables.
I believe the data members of the same access level in a struct will always be ordered in memory by the compiler, so I could define a struct somewhere, instantiate it in my dedicated linker section and extend it with future updates. But even then, I know just enough about alignment guarantees to know I don't know a whole lot about them, so I'm still not sure I'm safe.
So, how should I do this ?
Upvotes: 0
Views: 149
Reputation: 12610
Several compilers and/or linkers order variables by some (to us users) unknown (hashing?) algorithm. If you rename a variable or add a variable, each of the variables might change its location.
However, there is help, as the standard says in chapter 6.5.2.3 paragraph 6 (emphasis by me):
One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.
So if you define a structure for the saved data, you can append new members without fear. Use this structure to define the single variable of saved values.
Even more, you can define a union of structures, which have a common initial sequence of members that you can use to distinguish the sequence of following members.
Anyway, you need to locate this single variable by appropriate attributes and linker script entries. But you do this already.
Upvotes: 1