Hello,
I am using nRF Connect SDK v2.9.0. While working on the nRF52840 board, I used sys_poweroff() to put the board in deep sleep mode. But before calling it, I called
Hello,
I am using nRF Connect SDK v2.9.0. While working on the nRF52840 board, I used sys_poweroff() to put the board in deep sleep mode. But before calling it, I called
HI,
The system off demo demonstrate retention if build with CONFIG_APP_USE_RETAINED_MEM=y
. The RESETREAS exist on nRF54L15 as well, but is handled a bit differently in the SDK. You can refer to the print_reset_reason() function in the NFC system off sample which show how you can read it (the sample only decodes reasons relevant for the NFC sample, though).
When I added CONFIG_APP_USE_RETAINED_MEM=y, I got "attempt to assign the value 'y' to the undefined symbol APP_USE_RETAINED_MEM"
Also, I want to configure the retention in the running time before calling sys_poweroff()
In the reset reason, when I used print_reset_reason() function, I Got the same errors
I set CONFIG_APP_USE_RETAINED_MEM= y in the system_off sample but unfortunately, I got the same error "attempt to assign the value 'y' to the undefined symbol APP_USE_RETAINED_MEM"
Hi,
That is odd. It works on my end, and is an important part of the sample. Did you put CONFIG_APP_USE_RETAINED_MEM=y in prj.conf? Also, can you confirm that the system_off sample you are using is the one under zephyr/samples/boards/nordic/system_off/?
If it still does not work, can you share the full sample project with your modification as well as the build output so that I see exactly what you are doing and can attempt to reproduce on my end?
Yes, I added it in the prj.conf file. But the system_off sample I used is from nrf/samples/nfc/system_off/
I will try another system_off sample now
Einar Thorsrud The example in zephyr/samples/boards/nordic/system_off/ worked for me. But I need to know what the difference is between nrf_power_rampower_mask_on and the code in the example. Are they both used to keep the RAM content in Deep Sleep mode?
Hi,
The nrf_power_rampower_mask_on() function is more low level and is used under the hood. The method demonstrated in the System OFF sample is using the Zephyr APIs. The retained region is specified in the devicetree (see the overlay file for the board under "boards", where yuo have this for the nRF54L15 DK:
/ { cpuapp_sram@2002e000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x2002e000 DT_SIZE_K(4)>; zephyr,memory-region = "RetainedMem"; status = "okay"; retainedmem0: retainedmem { compatible = "zephyr,retained-ram"; status = "okay"; }; }; aliases { retainedmemdevice = &retainedmem0; }; }; &cpuapp_sram { /* Shrink SRAM size to avoid overlap with retained memory region */ reg = <0x20000000 DT_SIZE_K(184)>; ranges = <0x0 0x20000000 0x2e000>; };
This is the recommende approach.
If you are interested, you can follow this further down by inspecting code or debugging, and then you should see that then the implementation for nrf for the Zephyr retained mem driver in zephyr/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c is used, and this calls nrfx_ram_ctrl_retention_enable_set(). In there, you can see that a function pointer to ram_ctrl_block_section_retention_enable_set() is passed to ram_ctrl_block_section_iterate(), and within nrfx_ram_ctrl_section_retention_mask_enable_set(), nrf_power_rampower_mask_on() is called.
Hi,
The nrf_power_rampower_mask_on() function is more low level and is used under the hood. The method demonstrated in the System OFF sample is using the Zephyr APIs. The retained region is specified in the devicetree (see the overlay file for the board under "boards", where yuo have this for the nRF54L15 DK:
/ { cpuapp_sram@2002e000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x2002e000 DT_SIZE_K(4)>; zephyr,memory-region = "RetainedMem"; status = "okay"; retainedmem0: retainedmem { compatible = "zephyr,retained-ram"; status = "okay"; }; }; aliases { retainedmemdevice = &retainedmem0; }; }; &cpuapp_sram { /* Shrink SRAM size to avoid overlap with retained memory region */ reg = <0x20000000 DT_SIZE_K(184)>; ranges = <0x0 0x20000000 0x2e000>; };
This is the recommende approach.
If you are interested, you can follow this further down by inspecting code or debugging, and then you should see that then the implementation for nrf for the Zephyr retained mem driver in zephyr/drivers/retained_mem/retained_mem_nrf_ram_ctrl.c is used, and this calls nrfx_ram_ctrl_retention_enable_set(). In there, you can see that a function pointer to ram_ctrl_block_section_retention_enable_set() is passed to ram_ctrl_block_section_iterate(), and within nrfx_ram_ctrl_section_retention_mask_enable_set(), nrf_power_rampower_mask_on() is called.
OK, thank you for this information.
But I have another question, please, if I need to implement a function that enters the system in sleep mode, is there any way rather than calling k_sleep(K_FOREVER);
By sleep, do you mean system OFF sleep mode (where wakeup is in form of a reset), normal system ON sleep mode?
System On sleep is auomatically entered by the Zephyr idle thread, whenever there is no work to be done. That is for instance if all threads call k_sleep or are waiting for something.
For system off you can call sys_poweroff() as is demonstrated in the system off sample you have been looking at.
Yes, I mean system ON idle mode. Does that mean if I need to implement a function that enters the system in this mode, I should call k_sleep for all threads?
Hi,
Yes. As long as some threads have work to do (i.e. is not sleeping), the idle thread will not run. This is the same as for any other RTOS. So if you for insance want to wait/sleep, use k_sleep, as that will allow systme on sleep. If you instead with with for instance a loop (i.e. "busy wait"), the idle thread will not run, and the current consuption will be high. I recommend you go throught the nRF Connect fundamentals and intermediate courses (particularily Lesson 1 – Zephyr RTOS: Beyond the basics of the intemetiade course) to learn about this.