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

nRF52840 SDK16 S140 - How to put in RAM retention

Hi everyone,

I am working on a project where I have to enter the system into System OFF mode and RAM retention. What I actually want is to retain the value of some variables.

How could I do that in terms of software? Are there any specific functions I have to use? I also read that I have to make a no-init/zero_init section in order to ensure that the firmware does not clear the values at boot up but I don't even know what is this and how to implement it.

Could someone guide me? Or is there a similar example I could follow?

Thanks in advance

Nick

  • API: POWER HALnrf_power_rampower_mask_on.


     

    Are there any specific functions I have to use? I also read that I have to make a no-init/zero_init section in order to ensure that the firmware does not clear the values at boot up but I don't even know what is this and how to implement it.

     It depends on the compiler, which do you use? 

  • Hi haakonsh,

    Ok, what I have understood so far is that in order to keep retention in RAM you have to write on RAM[n].POWERSET register and if you are using a softdevice you have to use the sd_power_ram_power_set() API. right?

    By default the POWER field (bits A-P) is set while the RETENTION field (bits Q-f) of RAM[n].POWERSET register is unset. So in my case I have to configure only the RETENTION field (as I want RAM ON on system ON mode). What I have understand is that the RAM has 9 sections and you can select which of the sections to retain during system OFF..

    How can I find the memory section (n=0..8) that my variable is located?

    How do I know what bit positions (Q-f) I have to set?

    Moreover, RAM retention is not enough when you enter the system OFF mode, because the system restarts after waking up and the variables are initialized to zero. So you have to add the variables into the non_init section in order to avoid initialization during restart. This is done by using the zero_init attribute. However  I am a little confused regarding the syntax.. Taking for example the "state" variable, which of the following expression is correct?

    uint8_t state __attribute__((section(".zero_init"),zero_init));
    uint8_t state __attribute__((section(".zero_init")));
    uint8_t state __attribute__((zero_init));

    Also, should I include anything into the flash_placement.xml file?

    In flash_placement.xml there is the .non_init section. This is the same as the .zero_init?

    Maybe, I could use the expression uint8_t state __attribute__((section(".non_init"),zero_init))?

    Sorry for the big post.. I an new to this and I try to learn..

    Thanks in advance 

    Nick

  • Nikosant03 said:
    Ok, what I have understood so far is that in order to keep retention in RAM you have to write on RAM[n].POWERSET register and if you are using a softdevice you have to use the sd_power_ram_power_set() API. right?

     Yes, that's correct. 

    Nikosant03 said:

    By default the POWER field (bits A-P) is set while the RETENTION field (bits Q-f) of RAM[n].POWERSET register is unset. So in my case I have to configure only the RETENTION field (as I want RAM ON on system ON mode). What I have understand is that the RAM has 9 sections and you can select which of the sections to retain during system OFF..

    How can I find the memory section (n=0..8) that my variable is located?

    How do I know what bit positions (Q-f) I have to set?

    See Memory: RAM0-9 and the sections within each RAM block. The sections correspond to the Q-F bit positions. (S[i]RETENTION (i=0..15)). F.ex. if the variable is at address 0x2002 8420 that will be RAM8, section 3. 
     

    #Define RAM_SECTION_3 (1 << 19)
    #Define RAM_INSTANCE 8
    #Define RAM_ON_SYSTEMON 0xFFFF //All sections ON in SystemON
    
    err_code = sd_power_ram_power_set(RAM_INSTANCE, RAM_ON_SYSTEMON | RAM_SECTION_3);
    
    //There's also bitmasks and bitfield definitions in nrf_power.h:
    err_code = sd_power_ram_power_set(RAM_INSTANCE, NRF_POWER->RAM[RAM_INSTANCE].POWER | NRF_POWER_RAMPOWER_S3RETENTION_MASK);
    



     

    Nikosant03 said:
    Taking for example the "state" variable, which of the following expression is correct?

    From https://developer.arm.com/documentation/dui0472/m/compiler-specific-features/--attribute----zero-init---variable-attribute:

    uint8_t state __attribute__((zero_init)); will place the variable state in the .bss section.

    uint8_t state __attribute__((section("zero_init"), zero_init)); will place the variable state in the user-defined .zero_init section

    If you declare a user-defined section then you will most likely need to add it to the flash placement file in order to let the linker know that such a section exists. 

Related