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

nRF51 RAM retention after System Reset question.

Hello, I looked througth the devzone but didn't find direct answer. So created new one.

RM v3.0 states chapter 12.1.19 "Reset behavior" with table. However, it is not clear for me what crosses in table mean. In general, I want to use filled data array in RAM after calling NVIC_SystemReset(). I use softdevice and tried to do next:

uint32_t ramon_all= POWER_RAMON_ONRAM0_RAM0On  << POWER_RAMON_ONRAM0_Pos
                     | POWER_RAMON_ONRAM1_RAM1On  << POWER_RAMON_ONRAM1_Pos
                     | POWER_RAMON_OFFRAM0_RAM0On  << POWER_RAMON_OFFRAM0_Pos
                     | POWER_RAMON_OFFRAM1_RAM1On  << POWER_RAMON_OFFRAM1_Pos;
 static uint8_t myarray[64] __attribute__( ( section( "NoInit"), zero_init) ); //place it to NoInit section.
sd_softdevice_enable(...);
...
memset(myarray,0xA5,64);
...
uint32_t res=sd_power_ramon_set(ramon_all);  //check result
uint32_t ramon; 
res=sd_power_ramon_get(&ramon); //check result and value
sd_nvic_SystemReset();

After reset myarray filled with zeros.
The questions:

  1. Is RAM retention possible at system reset. If yes, how to make it possible or what is wrong in my code?

  2. What the link of NVIC_SystemReset(); in code with Table 12.1.19 "Reset behaviorchapter" in RM ? Does NVIC_SystemReset perform soft reset?

P.S. These threads helped me, but partially. Link , Link

  • Most likely thing is that myarray is being zero-filled as part of the startup despite the attribute you're setting. Depending on the IDE you're using, there may be more you have to set to really stop those sections being initialised. I'd work out where myarray is, put a breakpoint right at the start of the reset_handler and see what it is before any code runs at all. If it's full of data, you know the startup code is zeroing it and then you can work out how to stop that.

    Code for NVIC_SystemReset is in the CMSIS headers, it just performs a standard Cortex M0 reset, so yes, a soft reset. The table you mention however is nothing to do with memory, that's for retained registers. If you look underneath the table it tells you that RAM is never reset but may be corrupted. So technically you can't really do what you're trying to do, because there's no guarantee that RAM doesn't get corrupted. I've yet however to see a case in which it does get corrupted, but the manual does state it can, so you better have a way to detect that and recover.

    __STATIC_INLINE void NVIC_SystemReset(void)   
    {
      __DSB();                                                          /* Ensure all outstanding memory accesses included
                                                                       buffered write are completed before reset */
      SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                 SCB_AIRCR_SYSRESETREQ_Msk);
      __DSB();                                                          /* Ensure completion of memory access */
    
      for(;;)                                                           /* wait until reset */
      {
        __NOP();
      }
    }
    
  • Hi,

    I believe you're "almost" there. I suspect that you've not set "NoInit" on the RAM-block in your settings. A "Soft reset" is the same as doing a nvic_systemreset(); and it shall not clear your RAM as per our datasheet (be aware that the startup file may do so anyway!)

    Attached is a modified example (based on SDK11) that shows how to utilize this in a simple manner.

    ram_retention_example.zip

    Cheers, Håkon

Related