.noinit section

I was reading about the .noinit section here: http://www.nongnu.org/avr-libc/user-manual/mem_sections.html#sec_dot_noinit I tried to get it working in an Arduino sketch however my variables keep being initialized to 0. I want to use it to retain some variables in RAM across resets as it would be better than wearing out the EEPROM by doing excessive writes.

Does any one know how to get it working? Thanks.

I want to use it to retain some variables in RAM across resets as it would be better than wearing out the EEPROM by doing excessive writes.

While .noinit would be interesting functionality to get working I think you’re possibly being overly cautious about wearing out EEPROM.

How often is the reset and/or variable change likely to occur?

Without seeing your code it’s difficult to surmise why it’s not working as you expect.

–Phil.

I think you're possibly being overly cautious about wearing out EEPROM.

Yes you are probably right.

How often is the reset and/or variable change likely to occur?

I wanted to keep the current time in seconds across resets, however I should be getting a real-time clock soon (which also has 50-odd bytes of battery-backed RAM) so I won't need to worry about using the EEPROM at all.

So while I no longer need the .noinit section, it might be beneficial to other users.

So while I no longer need the .noinit section, it might be beneficial to other users.

That is very useful, I think I will add it to the software clock library in the playground. Not only is the data held through a reset, my USB freeduino board held the data in RAM with the power disconnected for more than 10 seconds.

FYI, here's how to use it in a sketch.

// variable to hold the time unsigned long savedTime attribute ((section (".noinit")));

// variable holding a 'magic' number to validate that the value in savedTime has been set. // remember that an unitialized variable will hold junk when the board voltage drops too low, we use this to check. int savedFlag attribute ((section (".noinit")));

In setup:

if(savedFlag == 1234){ // 1234 is the magic number used to flag valid noinit data Serial.print("using saved time "); Serial.println(savedTime,DEC); DateTime.sync(savedTime); // set the clock to the saved value } savedFlag = 1234; // make sure my flag is set

in loop:

savedTime = DateTime.now(); // copy the current time to our savedTime variable updated each iteration of the loop

Not only is the data held through a reset, my USB freeduino board held the data in RAM with the power disconnected for more than 10 seconds.

So it is working for you?

Here is my test sketch:

int savedFlag __attribute__ ((section(".noinit")));

void setup() {
  Serial.begin(9600);
  Serial.print("Old: ");
  Serial.println(savedFlag);
  savedFlag = 1234;
  Serial.print("New: ");
  Serial.println(savedFlag);
}

void loop() {
}

However every time after reset the value of savedFlag is always 0 (it is as if the .noinit section is not working).

I am using an Arduino Diecimila board on arduino-0011. I have tried using Windows Vista Ultimate 64-bit and Ubuntu 8.04 with the same results. Is the bootloader that is causing issues?

Its working, its just that your not printing what you think your printing. try this

int savedFlag __attribute__ ((section(".noinit")));

void setup() {
  Serial.begin(9600);
  Serial.print("Old: ");
  Serial.println(savedFlag,DEC); // note this prints the decimal value of the integer
  savedFlag = 1234;
  Serial.print("New: ");
  Serial.println(savedFlag,DEC);
}

void loop() {
}

Its working, its just that your not printing what you think your printing. try this

Unfortunately it is still not working. I copied your code exactly but I am still getting the same serial output regardless of how many times I reset the board:

Old: 0
New: 1234

Its very odd but the code works perfectly in my test sketch. But I have just discovered that it needs to be linked with my DateTime library. I don’t know if that is because of some other code used by the library or not but I will look at the assembler output when I get a chance and let you know.

You are welcome to try it yourself if you want, the library is here: http://www.arduino.cc/playground/Code/DateTime

You don’t need to call any functions in the library, just copy the code to a DateTime directory under the library directory and #include <DateTime.h>

This sketch worked for me:

#include <DateTime.h>

int savedValue __attribute__ ((section (".noinit")));
int savedFlag __attribute__ ((section (".noinit")));


void setup(){
   pinMode(13,OUTPUT);
   Serial.begin(9600);

   if(savedFlag == 1234){
       Serial.print("using saved value ");
       Serial.println(savedValue,DEC);
   }
   savedFlag = 1234;
   Serial.println("started");
 }

void loop(){
  Serial.println(savedValue,DEC);
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13,LOW);  
  delay(500);
  savedValue++ ;
}

If I determine what it is in the library code that makes noinit work I will let you know

So while I no longer need the .noinit section, it might be beneficial to other users.

That is very useful, I think I will add it to the software clock library in the playground. Not only is the data held through a reset, my USB freeduino board held the data in RAM with the power disconnected for more than 10 seconds.

I'm a little confused about why this is useful in that usage, given you don't know the elapsed time between when you lose power and when you regain it? I haven't looked closely at your code however so I could easily be missing something. :)

--Phil.

So while I no longer need the .noinit section, it might be beneficial to other users.

That is very useful, I think I will add it to the software clock library in the playground. Not only is the data held through a reset, my USB freeduino board held the data in RAM with the power disconnected for more than 10 seconds.

I'm a little confused about why this is useful in that usage, given you don't know the elapsed time between when you lose power and when you regain it? I haven't looked closely at your code however so I could easily be missing something. :)

--Phil.

It's useful because if a program running a clock resets, for example through a reset on the serial port, then the clock can continue to keep time. The clock may drop a second or so but for most timing applications that's much better than the time completely reset.

The brief retention through loss of power is less useful because if there are any peripherals connected to the arduino they are likely to drain power too quickly for RAM to retain its values.

But Its handy to have a clock or a counter variable in a sketch restart from where it was after reset

You are welcome to try it yourself if you want, the library is here: http://www.arduino.cc/playground/Code/DateTime

You don[ch8217]t need to call any functions in the library, just copy the code to a DateTime directory under the library directory and #include <DateTime.h>

I gave this a shot with no success :(. Variables are still 0 after a reset.
Thanks for your help so far. Maybe if could have some more testers we could narrow down what’s causing it to not work.

You are welcome to try it yourself if you want, the library is here: http://www.arduino.cc/playground/Code/DateTime

You don’t need to call any functions in the library, just copy the code to a DateTime directory under the library directory and #include <DateTime.h>

I gave this a shot with no success :(. Variables are still 0 after a reset.
Thanks for your help so far. Maybe if could have some more testers we could narrow down what’s causing it to not work.

To make sure that the linker is finding the library you could try this sketch

#include <DateTime.h>

int savedValue __attribute__ ((section (".noinit")));
int savedFlag __attribute__ ((section (".noinit")));


void setup(){
   pinMode(13,OUTPUT);
   Serial.begin(9600);

   if(savedFlag == 1234){
       Serial.print("using saved value ");
       Serial.println(savedValue,DEC);
   }
   else
      savedValue = 0;
      
   savedFlag = 1234;
   DateTime.sync( savedValue);
   Serial.println("started");
 }

void loop(){
  DateTime.available();
  savedValue = DateTime.now();
  Serial.println(savedValue, DEC);
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13,LOW);  
  delay(500);
}

To make sure that the linker is finding the library you could try this sketch

Still no success. Compiles and runs fine, just the .noinit variables are reinitialised to 0.

Its strange that same test code works for me with or without the actual calls to the library methods. But my guess is that it has nothing to do with the code and more with what the linker does under the covers.

I am testing with version 0011, are you?

FWIW, I had a look at the map files for sketches where noinit did and did not work, both contained the two noninit variables just after the end of the initialized data segment (__bss_end), so its not at all clear what is making the difference between initialising the values or not.

I am testing with version 0011, are you?

Yes indeed I am. Tried in both Windows Vista and Ubuntu.