This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reading back uninitialised variable after soft reset nRF52 GCC

I'm trying to set a global variable in RAM as uninitialised so it can be read back after a soft reset condition:

uint32_t data __attribute__((section("NoInit"), zero_init));

Results in:

warning: 'zero_init' attribute directive ignored [-Wattributes]

Of course it seems this variable is always 0 after reset

Ultimatly I'm trying to create a mechanism to return crash logs over BLE. The idea is that hardfault and APP SDK error variables will be saved into to a global struct before reset. On the next startup, this variable is reported back to the central device.


More Info

According to the gcc_startup_nrf52.S file, the .bss section is cleared if __STARTUP_CLEAR_BSS is defined. My project doesn't define this, so leads me to believe that nothing is cleared on startup. I see that my section call is indeed placing the variable inside a .NoInit section without any extra flags.

The other method I'm trying is to use the RAM Retention example in the SDK where they call SYSTEMOFF after writing to RAM (There doesn't seem to be anything special about this RAM location)

#define RAM_MEMORY_TEST_ADDRESS (0x20002000UL)

uint32_t * volatile p_ram_test = (uint32_t *)RAM_MEMORY_TEST_ADDRESS;

*p_ram_test = RAM_MEMORY_TEST_WORD;

NRF_POWER->SYSTEMOFF = 0x1;

As I'm calling a soft reset the RAM should be fully retained (as specified in the data sheet), so I think this should be the same behaviour. My problem is that the NRF debugger will pin reset the IC on every startup. According to the datasheet, this will clear RAM. I can only use the RTT in this case to print the values. The soft reset makes the RTT loose some data before the reset, but I still see that the values is 0 after power on.

Could my problem be related to the fact that I have a debugger connected that is somehow clearing my RAM?

  • But soft reset works as any other reset = RAM is erased. I'm afraid this kind of information preserving won't work... at least all similar systems of "Hard fault logging" on nRF5x I've seen so far were using NVM (= allocating one or more flash pages and implementing simpler or more complex systems how to log/retrieve/interpret/report/clean the fault events).

  • zero_init isn't a defined GCC attribute so that's why it's ignored. Do you actually have a NoInit section in your linker file and if so what are its attributes. The most likely thing is it's being placed in a section which is zero-erased on startup. You need to go debug the startup code which is called after the reset handler and find out which sections are neither zero-filled, nor loaded from flash.

    @endnode - RAM is not erased on reset. There's no guarantee it doesn't get corrupted but it's not erased. My experience is I've never yet seen it corrupted either but I'm sure it happens.

  • Thx, not erased (by itself) but "unpredictable" (and should be init during start-up sequence which hammerfet want's to skip). My misunderstanding.

  • According to section 18.8 (page 83) of the nRF52 datasheet, the table shows that for both CPU lockup and soft reset, the RAM is preserved.

    The conditions where RAM may be corrupted are for power and pin reset reasons. This is fine because I report back POWER->RESETREAS along with my stored data. If the reset was caused by a condition that would have corrupted RAM, then I ignore the saved data anyway. For the soft reset condition (which both app error and hardfault cause), I should be fine to read back the RAM

  • it's 'lose' not 'loose'.

    The datasheet doesn't say a pin reset clears RAM. None of the resets clear RAM, RAM contents is not guaranteed to be preserved, but it's not cleared, here's the note from the datasheet

    Note: The RAM is never reset, but depending	on reset source, RAM content may be corrupted.
    

    My experience has been it's never corrupted either.

    You need to put a breakpoint on the reset handler, either your reset handler or the bootloader one. Find the address at 0x00000004 and breakpoint that (minus 1). You want the debugger to halt AS SOON as reset happens before even one instruction of code has been run. If your RAM location is zero then when it wasn't before the reset, I'm wrong and you can't do this. If it's not zero, something is zeroing it. Never mind the nrf52 startup file, gcc has its own crt0 (or equivalent) which is doing loads of copies and zeroes.

Related