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

RAM retention issue

Hi,

I am using NRF52832 with softdevice s112 and SDK 15.3. I have 20 bytes of data which I want to retain in RAM during system off. I use the following code so that the data is not initialized.

uint8_t m_addl_adv_manuf_data[ADV_ADDL_MANUF_DATA_LEN] __attribute__ ((section(".noinit")));

Then in main, I get the slave and section and set the ram retention on. I checked the value and my variable belongs in slave 1 section 0 and I set the power to 0x1FFFF. But the value is not retained after wakeup from system off

uint32_t p_offset = (uint32_t)(&m_addl_adv_manuf_data[0] - RAM_START_ADDRESS);
uint8_t ram_slave_n = (p_offset / 8192);
uint8_t ram_section_n = (p_offset % 8192)/4096;
NRF_LOG_INFO(" addr %x offset %x RAM section %d, slave %d",&m_addl_adv_manuf_data[0],p_offset,ram_slave_n,ram_section_n);
sd_power_ram_power_set(ram_slave_n,(1 << ram_section_n) << POWER_RAMON_OFFRAM0_Pos);
uint32_t ram_power;
sd_power_ram_power_get(ram_slave_n,&ram_power);
NRF_LOG_INFO("power %x",ram_power);

On the other hand, If I assign the variable m_addl_adv_manuf_data to some other slave and section (slave 4 and section 0) 0x20008000 by using the sample code then even if I do not enable the RAM retention in the power register, it is still able to retain the value. This is really confusing. Can you explain why ?


#define RAM_MEMORY_TEST_ADDRESS (0x20008000UL)

Thanks,

Jyoti

Parents
  • Hi Jyoti,

    The power settings are retained until you power cycle the chip, maybe that could explain why you didn't have to enable retention for the second test.

    Are you using Keil/SES or GCC? I wonder if the m_addl_adv_manuf_data variable gets placed correctly in a "non initialized" section since it seems to work when you use RAM_MEMORY_TEST_ADDRESS pointer.  

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for the response. Does that mean that we do not need ram retention if NRF52 just waking up from system off mode. As the RAM is not reset when waking up from system off then I can expect for it to retain it's content.

    I am using Keil. How do I know if it is placed correctly in non initialized section? what is the correct way of putting it on non initialized section?

    Thanks,

    Jyoti

Reply
  • Hi Vidar,

    Thanks for the response. Does that mean that we do not need ram retention if NRF52 just waking up from system off mode. As the RAM is not reset when waking up from system off then I can expect for it to retain it's content.

    I am using Keil. How do I know if it is placed correctly in non initialized section? what is the correct way of putting it on non initialized section?

    Thanks,

    Jyoti

Children
  • I am using Keil. How do I know if it is placed correctly in non initialized section?

    Check the Linker Map file.

    what is the correct way of putting it on non initialized section?

    Whatever it is would not be specific to Nordic - so check Keil documentation.

    Search the Keil forum: http://www.keil.com/forum/

  • Hi Jyoti,

    Jyoti said:
    Thanks for the response. Does that mean that we do not need ram retention if NRF52 just waking up from system off mode. As the RAM is not reset when waking up from system off then I can expect for it to retain it's content.

    Sorry, I meant to say that the RAM power settings are retained, not the RAM itself. RAM blocks are power gated in system OFF so you cannot expect data to be kept without retention enabled. Also, note that in debug interface mode the device will enter emulated system OFF mode, which means that RAM will remain on. That could be another reason for why you didn't have to enable retention in your test. 

    I have made an example based on the ble_app_uart project in sdk 15.3.0 with a "noinit" section placed at the end of RAM. The project is attached below along with some screenshots showing relevant project settings. Hope this helps.  

    Adding IRAM2 for NoInit data:

    I have not found a way to selectively chose which variables to place in NoInit without touching the Scatter file so  l defined the m_addl_adv_manuf_data variable in a separate source file:

    And the *.map file confirms that m_addl_adv_manuf_data got placed in IRAM2

    Example project. You can test it by performing the following steps:

    1. Extract zip and copy it to \nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral. Compile and program

    2. Power cycle the board to ensure that the chip goes out of debugging mode

    3. Open a serial client and open the Jlink COM port (assuming you have a DK)

    4. The app will enter system OFF mode after 5 seconds of advertising

    5. Wait 5 seconds and press button 1 on the DK for wake-up

    6. You should see the "Valid data in no init section" message in the UART log if the data was retained. 

    ble_app_uart_w_ram_retention_test.zip

  • Hi Vidar,

    Thanks for the response and the example. I have not defined DEBUG in the project settings and I am not debugging the project from the IDE. But I do have the Segger RTT Viewer open to look at the log. Does that mean the program is running in debug interface mode?

    Also, I have evaluation version of keil, so I think scatter file will not work. How do I do the similar thing of creating IRAM2 in IAR?

    Thanks,

    Jyoti

  • Hi Jyoti,

    Jyoti said:
    But I do have the Segger RTT Viewer open to look at the log. Does that mean the program is running in debug interface mode?

    Yes, RTT goes through the debug interface.

    Jyoti said:
    Also, I have evaluation version of keil, so I think scatter file will not work

    That's correct. You can't edit the scatter file in the lite version. This is why I didn't use the scatter file in the example I sent you. 

    For IAR it shouldn't be necessary to create a new linker section. You can try to define your variable like this:

    __no_init uint8_t m_addl_adv_manuf_data[ADV_ADDL_MANUF_DATA_LEN] @ <RAM address> ; (IAR doc)
    Or if you chose to use Segger embedded Studio:
    uint8_t m_addl_adv_manuf_data[ADV_ADDL_MANUF_DATA_LEN]  __attribute__((section(".non_init")));
Related