.noinit section on Due

I'm trying to use the .noinit section to retain data across resets on an Arduino Due. This is part of a simple datalogger project I want to give my students as a programming exercise. From what I've read this should be as simple as declaring the variable I want to retain like this:

unsigned TestVal attribute ((section (".noinit")));

However when I write a little test program (below) to try this out I find that TestVal is always zero. It appears that the variable's memory location can't be written to.

//Simple program to test whether we can 
//distinguish a power-on reset from a soft reset.

#define   TEST_VAL 189;

unsigned TestVal __attribute__ ((section (".noinit")));
//unsigned TestVal;

void setup() {
  // put your setup code here, to run once:
  TestVal = TEST_VAL;


void loop() {
  // put your main code here, to run repeatedly:


If I remove the attribute ((section (".noinit"))) qualifier then TestVal prints as 0 in setup() and correctly as 189 in loop(), ie. exactly as you'd expect for a variable that isn't in .noinit.

Digging around in the linker map file it appears that with the .noinit attribute TestVal is being put at address 0x00082a54, which is in the internal FLASH address space of the SAM3X8E chip, which would explain why the program can't write to it. Without the .noinit attribute it ends up in the static RAM address space as you'd expect.

I thought I'd be able to rectify this by using a linker flag in the platform.txt file to specify the address of the .noinit section as being in the SRAM address space (eg. -Wl,--section-start=.noinit=0x20008000), but although that compiled and linked OK I then got an error from the loader telling me the program was too big to go in the FLASH.

I've now run out of ideas - any assitance would be appreciated!

from our stm32 brethren:


I was able to make it work by adding a .noinit section definition to .../hardware/sam/1.6.4/variants/arduino_due_x/linker_scripts/gcc/flash.ld

/* (original) */

    /* .bss section which is used for uninitialized data */
    .bss ALIGN(4) (NOLOAD) :
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

/* add this: */
/* copied from above and adjusted */

    /* .noinit section which is used for uninitialized data that won't be zeroed at startup */
    .noinit ALIGN(4) (NOLOAD) :
        . = ALIGN(4);
        _snoinit = . ;
        *(.noinit .noinit.*)
        . = ALIGN(4);
        _enoinit = . ;
    } > ram

However, there is a big limitation: according to my tests the SRAM contents are retained only if the reset line is held low for at most 150 milliseconds. Opening a serial connection to the programming port pulls the reset line low for 200 ms.