For a number of reasons I have been using the attribute ((section(".noinit"))) declaration in many sketches.
Actually, when using the UNO Minima the compiler still accepts that declaration but simply ignores it. The only work-around is using the EEPROM which will work for a while. Is there any better solution?
Check it out:
float pi __attribute__ ((section(".noinit")));
byte keepMyValue __attribute__ ((section(".noinit")));
void setup() {
Serial.begin(9600);
if (pi != PI) {
/*
cold-start detected
this code is only executed
after power-up
*/
keepMyValue = 1;
// next start will be NO coldstart
pi = PI;
}
else keepMyValue++;
/*
Even (re)opening the Serial monitor
will increase keepMyValue.
On each start the number of flashes
of the LED will be one higher.
On UPLOAD keepMyValue gets incremented
twice.
*/
Serial.println(keepMyValue);
pinMode(LED_BUILTIN, OUTPUT);
for (int i = 0; i < keepMyValue; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
}
void loop() {}
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 4] .noinit NOBITS 200000b0 0100b0 000020 00 WA 0 0 4
You can see that the keepMyValue variable is placed at the beginning of the .noinit section. You can also verify that the section is not loaded by the startup code.
Are there any guarantees that the state of SRAM is preserved across (warm) resets?
And even if the value of pi is preserved, how can you be sure that the value of keepMyValue was not corrupted?
This whole approach seems very hacky at best.
Hi, PieterP, thank you for your posting. (Lots of keywords you are using I never came accross before.) As I switched to R4 only recently, there was a bad mistake in my example: though I prefer pi to dead beef, I should have noticed that floating point constants now are declared as double. But neither using double pi nor dead beef my intensiones materialized (possibly because disconnecting/reconnecting to USB when pressing the RESET button), so I have stay with the EEPROM. Nevertheless, thanks again.