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

ram retention nrf52

Hello,

I've taken the example from the SDK 12.0.0 for RAM retention. I've added additional NRF_LOG statements to check if the RAM retention is happening. I do not have the softdevice enabled for my application. But it is not working.

See the main.c

At line number 184, I see that the value RAM_MEMORY_TEST_WORD is stored at RAM address RAM_MEMORY_TEST_ADDRESS. So after performing system off and then again wakeup using button 1, at line number 117, I expect that the value at address RAM_MEMORY_TEST_ADDRESS is displayed in the log. But this is not happening.

I have gone through the post here which talks about taking care of data being zeroed at startup. But even then, it did not work. I'm also attaching the linker file also here Example_App_gcc_nrf52.ld

I also tried with defining the variables using the following code hoping that this variable value will be retained at systemoff and at systemon. But it is not.

static uint8_t VarName __attribute__ ((section(".noinit")));

I also tried to make the changes based on the errata finding documented here in section 3.31. But even that did not help.

Could anyone of you please help? My requirement is to enable RAM retention for a section of memory without using softdevice.

Thanks in advance.

Parents
  • Hi Manish.

    RAM in nRF52 can be subdivided into RAM slave blocks. Each slave block are divided 2 into 4KB sections (1 slave = 2 sections = 2 * 4KB = 8KB)

    Read the memory address pointed by the pointer p_ram_test and calculate which slave and section it belongs.

    #define RAM_START_ADDRESS  0x20000000
    
    uint32_t p_offset = (p_ram_test - RAM_START_ADDRESS);
    uint8_t ram_slave_n    = (p_offset / 8192);  
    uint8_t ram_section_n = (p_offset % 8192)/4096;
    
    NRF_POWER->RAM[ram_slave_n].POWERSET = ((1 << ram_section_n) << POWER_RAMON_OFFRAM0_Pos);
    

    If you are using softdevice and have enabled it, then at the time of this writing, softdevice still does not support RAM[0], instead it supports legacy interface RAMON register. So you have to use sd_power_ramon_set to control it.

    sd_power_ramon_set(((1 << ram_section_n) << POWER_RAMON_OFFRAM0_Pos));
    

    You have to make sure that this part of RAM slave have been selected for NOINIT section in your project or scatter file.

    Note: I did not test this code in any program even though i think it should work, just use this as a pseudo code to get the idea.

Reply
  • Hi Manish.

    RAM in nRF52 can be subdivided into RAM slave blocks. Each slave block are divided 2 into 4KB sections (1 slave = 2 sections = 2 * 4KB = 8KB)

    Read the memory address pointed by the pointer p_ram_test and calculate which slave and section it belongs.

    #define RAM_START_ADDRESS  0x20000000
    
    uint32_t p_offset = (p_ram_test - RAM_START_ADDRESS);
    uint8_t ram_slave_n    = (p_offset / 8192);  
    uint8_t ram_section_n = (p_offset % 8192)/4096;
    
    NRF_POWER->RAM[ram_slave_n].POWERSET = ((1 << ram_section_n) << POWER_RAMON_OFFRAM0_Pos);
    

    If you are using softdevice and have enabled it, then at the time of this writing, softdevice still does not support RAM[0], instead it supports legacy interface RAMON register. So you have to use sd_power_ramon_set to control it.

    sd_power_ramon_set(((1 << ram_section_n) << POWER_RAMON_OFFRAM0_Pos));
    

    You have to make sure that this part of RAM slave have been selected for NOINIT section in your project or scatter file.

    Note: I did not test this code in any program even though i think it should work, just use this as a pseudo code to get the idea.

Children
  • Hello Aryan,

    I took the hint from your reply to have a section of NOINIT in linker file. I did not use the logic provided above to determine where the variable is placed. I forced it to this NOINIT section while defining it.

    To make it clear, I edited my question to make it clear what exactly I did.

    I'm sorry if you are offended that I did not reply to your answer. Please excuse me for that.

    But even after doing all this, I still do not have an answer how to make the RAM retention work without softdevice. Please let me know if you can support.

  • Hi Manishk,

    I was not offended, but just trying to maintain some etiquette. Since you are new to this forum, i can understand that you did not knew about this. This is very well behaved decent and professional forum and we would like to maintain it this way. Thanks for understanding that.

    Please create a support case and attach your project there. We can find the problem sooner this way and we will update the answer here when we can can find what was wrong. Do not forget to give exact nRF hardware revision you are using

  • Hi Aryan,

    I've taken the example of RAM retention from SDK 12.0.0. I just added some NRF_LOG statements to check if I can see after system wakeup, if we have the right values in pointer p_ram_test. I was doing this using eclipse platform. There I had the NRF logging on serial port enabled. With this, it was not working.

    But upon your request for the project, I ran the keil project from "..\nRF5_SDK_12.0.0_12f24da\examples\peripheral\ram_retention\pca10040\blank\arm5_no_packs\ram_retention_pca10040.uvprojx" using the same main.c which I had already attached previously. But for some reason, when I try to enable NRF logging from Keil project, I get errors.

    Could you please use the main.c file which I've attached here and then try the same on the existing keil project with NRF logging enabled? If you see that the values are ok, then I know that there is something wrong in my eclipse settings. The nRF hardware which I've is nRF52832.

    Thanks in advance.

  • Sorry for the late response ManishK. I just tried your main.c and yes there are compilation errors because the peripheral examples are not constructed for logging. You can fix this by comparing the sdk_config-h file from example that has logging like sdk\examples\ble_peripheral. A lot of macros are missing in the sdk_config.h file in the ram_retention example.

    you also need to add files like nrf_log_frontend.c and other dependencies to the project.

Related