EEPROM space, as already mentioned, will work if non-volatile is required. However, you have not qualified if it needs to be non-volatile or not. If not then you can use an __attribute__ to define the variable space not to be initialized. As the SRAM on the ATmega's are not cleared by reset or power cycle. The Compiler defaults to initializing them. Where this can be turned off per variable as in the below example:
//non-initialized value
union configUnion{
uint8_t byte[6]; // match the below struct...
struct {
uint16_t value1;
uint16_t value2;
uint16_t chksum;
} val ;
} config __attribute__ ((section (".noinit")));
void setup() {
uint16_t sum;
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// prints title with ending line break
Serial.print("Out of Reset -");
sum = getchksum();
printValues();
if (sum != config.val.chksum) {
config.val.chksum = sum;
Serial.print("chksum is incorrect setting config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
config.val.value1++;
config.val.value2++;
Serial.print("setup new values - ");
printValues();
config.val.chksum = getchksum();
Serial.print("updating chksum config.val.chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
int counter = 0;
void loop() {
if (counter < 200) {
Serial.print("after a while - ");
printValues();
Serial.println();
while (true) {
continue;
}
}
counter++;
}
void printValues() {
Serial.print(" value1 = 0x"); Serial.print(config.val.value1, HEX);
Serial.print(", value2 = 0x"); Serial.print(config.val.value2, HEX);
Serial.print(", sum = 0x"); Serial.print(getchksum(), HEX);
Serial.print(", chksum = 0x"); Serial.println(config.val.chksum, HEX);
}
uint16_t getchksum() {
int sum = 0;
for (int position = 0; position < (sizeof(config) - sizeof(config.val.chksum)); position++) {
sum = sum + config.byte[position];
}
return sum;
}
Output of above code is below. Note that the first output was the result of powering the UNO up with the Reset button depressed and then released after the Monitor window was started. Otherwise the "incorrect setting" print would have been missed, before the monitor window can be started.
Out of Reset - value1 = 0xBFED, value2 = 0xD2F9, sum = 0x377, chksum = 0xF457
chksum is incorrect setting config.val.chksum = 0x377
setup new values - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x377
updating chksum config.val.chksum = 0x379
after a while - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
Out of Reset - value1 = 0xBFEE, value2 = 0xD2FA, sum = 0x379, chksum = 0x379
setup new values - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x379
updating chksum config.val.chksum = 0x37B
after a while - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
Out of Reset - value1 = 0xBFEF, value2 = 0xD2FB, sum = 0x37B, chksum = 0x37B
setup new values - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37B
updating chksum config.val.chksum = 0x37D
after a while - value1 = 0xBFF0, value2 = 0xD2FC, sum = 0x37D, chksum = 0x37D
With this your variables will persist resets. As long as the power is not lost. Noting the above where you will get random data, to start.
Using either EEPROM or .noinit I would recommend that you checksum your persistent variable space during setup and if incorrect you can initialize or issue a warning.