Skip to content

Commit 0a2e205

Browse files
nika-nordicjukkar
authored andcommitted
[nrf fromlist] samples: nordic: system_off: use retained_mem on all targets
Using bare-metal approach for retention configuration is no longer compatible with sys_poweroff() implementation. Upstream PR #: 82262 Signed-off-by: Nikodem Kastelik <[email protected]> (cherry picked from commit 15ffa30)
1 parent 49e3fe1 commit 0a2e205

11 files changed

+72
-181
lines changed

samples/boards/nordic/system_off/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
55
project(nrf_system_off)
66

77
target_sources(app PRIVATE src/main.c)
8-
if (CONFIG_APP_USE_NRF_RETENTION OR CONFIG_APP_USE_RETAINED_MEM)
8+
if (CONFIG_APP_USE_RETAINED_MEM)
99
target_sources(app PRIVATE src/retained.c)
1010
endif()

samples/boards/nordic/system_off/Kconfig

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,9 @@
33

44
mainmenu "Nordic SYSTEM_OFF demo"
55

6-
choice
7-
prompt "Use retention"
8-
optional
9-
10-
config APP_USE_NRF_RETENTION
11-
bool "Use state retention in system off using nRF POWER"
12-
depends on SOC_COMPATIBLE_NRF52X && CRC
13-
help
14-
On some Nordic chips this application supports retaining
15-
memory while in system off using POWER peripheral.
16-
Select this to enable the feature.
17-
186
config APP_USE_RETAINED_MEM
197
bool "Use state retention in system off using retained_mem driver"
20-
depends on RETAINED_MEM
21-
22-
endchoice
8+
select RETAINED_MEM
239

2410
config GRTC_WAKEUP_ENABLE
2511
bool "Use GRTC to wake up device from system off"

samples/boards/nordic/system_off/README.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ deep sleep on Nordic platforms.
1313
RAM Retention
1414
=============
1515

16-
This sample can also can demonstrate RAM retention. By selecting
17-
``CONFIG_APP_USE_NRF_RETENTION=y`` or ``CONFIG_APP_USE_RETAINED_MEM=y``
18-
state related to number of boots, number of times system off was entered,
19-
and total uptime since initial power-on are retained in a checksummed data structure.
16+
This sample can also demonstrate RAM retention.
17+
By selecting ``CONFIG_APP_USE_RETAINED_MEM=y`` state related to number of boots,
18+
number of times system off was entered, and total uptime since initial power-on
19+
are retained in a checksummed data structure.
2020
RAM is configured to keep the containing section powered while in system-off mode.
2121

2222
Requirements
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/ {
2+
sram0@2003f000 {
3+
compatible = "zephyr,memory-region", "mmio-sram";
4+
reg = <0x2003f000 DT_SIZE_K(4)>;
5+
zephyr,memory-region = "RetainedMem";
6+
status = "okay";
7+
8+
retainedmem0: retainedmem {
9+
compatible = "zephyr,retained-ram";
10+
status = "okay";
11+
};
12+
};
13+
14+
aliases {
15+
retainedmemdevice = &retainedmem0;
16+
};
17+
};
18+
19+
&sram0 {
20+
/* Shrink SRAM size to avoid overlap with retained memory region */
21+
reg = <0x20000000 DT_SIZE_K(252)>;
22+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/ {
2+
sram0@20007000 {
3+
compatible = "zephyr,memory-region", "mmio-sram";
4+
reg = <0x20007000 DT_SIZE_K(4)>;
5+
zephyr,memory-region = "RetainedMem";
6+
status = "okay";
7+
8+
retainedmem0: retainedmem {
9+
compatible = "zephyr,retained-ram";
10+
status = "okay";
11+
};
12+
};
13+
14+
aliases {
15+
retainedmemdevice = &retainedmem0;
16+
};
17+
};
18+
19+
&sram0 {
20+
/* Shrink SRAM size to avoid overlap with retained memory region */
21+
reg = <0x20000000 DT_SIZE_K(28)>;
22+
};

samples/boards/nordic/system_off/sample.yaml

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,17 @@ tests:
2222
- "system off demo"
2323
- "Retained data not supported"
2424
- "Entering system off; press sw0 to restart"
25-
sample.boards.nrf.system_off.nrf_retained:
25+
sample.boards.nrf.system_off.retained_mem:
2626
integration_platforms:
2727
- nrf52840dk/nrf52840
2828
platform_allow:
2929
- nrf52840dk/nrf52840
3030
- nrf52dk/nrf52832
31-
extra_configs:
32-
- CONFIG_APP_USE_NRF_RETENTION=y
33-
harness: console
34-
harness_config:
35-
type: multi_line
36-
ordered: true
37-
regex:
38-
- "system off demo"
39-
- "Retained data: INVALID"
40-
- "Boot count: 1"
41-
- "Off count: 0"
42-
- "Active Ticks:"
43-
- "Entering system off; press sw0 to restart"
44-
sample.boards.nrf.system_off.retained_mem:
45-
extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay"
46-
platform_allow:
4731
- nrf54l15dk/nrf54l15/cpuapp
32+
- nrf54l15dk/nrf54l10/cpuapp
33+
- nrf54l15dk/nrf54l05/cpuapp
4834
extra_configs:
4935
- CONFIG_APP_USE_RETAINED_MEM=y
50-
- CONFIG_RETAINED_MEM=y
5136
harness: console
5237
harness_config:
5338
type: multi_line
@@ -62,6 +47,8 @@ tests:
6247
sample.boards.nrf.system_off.grtc_wakeup:
6348
platform_allow:
6449
- nrf54l15dk/nrf54l15/cpuapp
50+
- nrf54l15dk/nrf54l10/cpuapp
51+
- nrf54l15dk/nrf54l05/cpuapp
6552
extra_configs:
6653
- CONFIG_GRTC_WAKEUP_ENABLE=y
6754
harness: console
@@ -79,13 +66,13 @@ tests:
7966
- "Retained data not supported"
8067
- "Entering system off; wait 2 seconds to restart"
8168
sample.boards.nrf.system_off.retained_mem.grtc_wakeup:
82-
extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay"
8369
platform_allow:
8470
- nrf54l15dk/nrf54l15/cpuapp
71+
- nrf54l15dk/nrf54l10/cpuapp
72+
- nrf54l15dk/nrf54l05/cpuapp
8573
extra_configs:
8674
- CONFIG_APP_USE_RETAINED_MEM=y
8775
- CONFIG_GRTC_WAKEUP_ENABLE=y
88-
- CONFIG_RETAINED_MEM=y
8976
harness: console
9077
harness_config:
9178
type: multi_line

samples/boards/nordic/system_off/src/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ int main(void)
3535

3636
printf("\n%s system off demo\n", CONFIG_BOARD);
3737

38-
if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
38+
if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
3939
bool retained_ok = retained_validate();
4040

4141
/* Increment for this boot attempt and update. */
@@ -81,7 +81,7 @@ int main(void)
8181
return 0;
8282
}
8383

84-
if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
84+
if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
8585
/* Update the retained state */
8686
retained.off_count += 1;
8787
retained_update();

samples/boards/nordic/system_off/src/retained.c

Lines changed: 13 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -15,147 +15,24 @@
1515
#include <zephyr/sys/byteorder.h>
1616
#include <zephyr/sys/crc.h>
1717

18-
#if CONFIG_APP_USE_NRF_RETENTION
19-
#include <hal/nrf_power.h>
20-
21-
/* nRF52 RAM (really, RAM AHB slaves) are partitioned as:
22-
* * Up to 8 blocks of two 4 KiBy byte "small" sections
23-
* * A 9th block of with 32 KiBy "large" sections
24-
*
25-
* At time of writing the maximum number of large sections is 6, all
26-
* within the first large block. Theoretically there could be more
27-
* sections in the 9th block, and possibly more blocks.
28-
*/
29-
30-
/* Inclusive address of RAM start */
31-
#define SRAM_BEGIN (uintptr_t)DT_REG_ADDR(DT_NODELABEL(sram0))
32-
33-
/* Exclusive address of RAM end */
34-
#define SRAM_END (SRAM_BEGIN + (uintptr_t)DT_REG_SIZE(DT_NODELABEL(sram0)))
35-
36-
/* Size of a controllable RAM section in the small blocks */
37-
#define SMALL_SECTION_SIZE 4096
38-
39-
/* Number of controllable RAM sections in each of the lower blocks */
40-
#define SMALL_SECTIONS_PER_BLOCK 2
41-
42-
/* Span of a small block */
43-
#define SMALL_BLOCK_SIZE (SMALL_SECTIONS_PER_BLOCK * SMALL_SECTION_SIZE)
44-
45-
/* Number of small blocks */
46-
#define SMALL_BLOCK_COUNT 8
47-
48-
/* Span of the SRAM area covered by small sections */
49-
#define SMALL_SECTION_SPAN (SMALL_BLOCK_COUNT * SMALL_BLOCK_SIZE)
50-
51-
/* Inclusive address of the RAM range covered by large sections */
52-
#define LARGE_SECTION_BEGIN (SRAM_BEGIN + SMALL_SECTION_SPAN)
53-
54-
/* Size of a controllable RAM section in large blocks */
55-
#define LARGE_SECTION_SIZE 32768
56-
57-
#elif CONFIG_APP_USE_RETAINED_MEM
18+
#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(retainedmemdevice))
5819
const static struct device *retained_mem_device = DEVICE_DT_GET(DT_ALIAS(retainedmemdevice));
59-
#endif
60-
61-
/* Set or clear RAM retention in SYSTEM_OFF for the provided object.
62-
*
63-
* @param ptr pointer to the start of the retainable object
64-
*
65-
* @param len length of the retainable object
66-
*
67-
* @param enable true to enable retention, false to clear retention
68-
*/
69-
static int ram_range_retain(const void *ptr,
70-
size_t len,
71-
bool enable)
72-
{
73-
int rc = 0;
74-
75-
#if CONFIG_APP_USE_NRF_RETENTION
76-
/* This only works for nRF52 with the POWER module.
77-
* The other Nordic chips use a different low-level API,
78-
* which is not currently used by this variant.
79-
*/
80-
uintptr_t addr = (uintptr_t)ptr;
81-
uintptr_t addr_end = addr + len;
82-
83-
/* Error if the provided range is empty or doesn't lie
84-
* entirely within the SRAM address space.
85-
*/
86-
if ((len == 0U)
87-
|| (addr < SRAM_BEGIN)
88-
|| (addr > (SRAM_END - len))) {
89-
return -EINVAL;
90-
}
91-
92-
/* Iterate over each section covered by the range, setting the
93-
* corresponding RAM OFF retention bit in the parent block.
94-
*/
95-
do {
96-
uintptr_t block_base = SRAM_BEGIN;
97-
uint32_t section_size = SMALL_SECTION_SIZE;
98-
uint32_t sections_per_block = SMALL_SECTIONS_PER_BLOCK;
99-
bool is_large = (addr >= LARGE_SECTION_BEGIN);
100-
uint8_t block = 0;
101-
102-
if (is_large) {
103-
block = 8;
104-
block_base = LARGE_SECTION_BEGIN;
105-
section_size = LARGE_SECTION_SIZE;
106-
107-
/* RAM[x] supports only 16 sections, each its own bit
108-
* for POWER (0..15) and RETENTION (16..31). We don't
109-
* know directly how many sections are present, so
110-
* assume they all are; the true limit will be
111-
* determined by the SRAM size.
112-
*/
113-
sections_per_block = 16;
114-
}
115-
116-
uint32_t section = (addr - block_base) / section_size;
117-
118-
if (section >= sections_per_block) {
119-
block += section / sections_per_block;
120-
section %= sections_per_block;
121-
}
122-
123-
uint32_t section_mask =
124-
(POWER_RAM_POWERSET_S0RETENTION_On
125-
<< (section + POWER_RAM_POWERSET_S0RETENTION_Pos));
126-
127-
if (enable) {
128-
nrf_power_rampower_mask_on(NRF_POWER, block, section_mask);
129-
} else {
130-
nrf_power_rampower_mask_off(NRF_POWER, block, section_mask);
131-
}
132-
133-
/* Move to the first address in the next section. */
134-
addr += section_size - (addr % section_size);
135-
} while (addr < addr_end);
136-
#elif CONFIG_APP_USE_RETAINED_MEM
137-
/* Retention setting cannot be controlled runtime with retained_mem API */
138-
(void)enable;
139-
rc = retained_mem_write(retained_mem_device, 0, ptr, len);
14020
#else
141-
#error "Unsupported retention setting"
21+
#error "retained_mem region not defined"
14222
#endif
14323

144-
return rc;
145-
}
146-
147-
/* Retained data must be defined in a no-init section to prevent the C
148-
* runtime initialization from zeroing it before anybody can see it.
149-
* It is not necesarry when retained_mem driver is utilized
150-
* as in this case retained data is stored in an area not initialized in runtime.
151-
*/
152-
__noinit struct retained_data retained;
24+
struct retained_data retained;
15325

15426
#define RETAINED_CRC_OFFSET offsetof(struct retained_data, crc)
15527
#define RETAINED_CHECKED_SIZE (RETAINED_CRC_OFFSET + sizeof(retained.crc))
15628

15729
bool retained_validate(void)
15830
{
31+
int rc;
32+
33+
rc = retained_mem_read(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained));
34+
__ASSERT_NO_MSG(rc == 0);
35+
15936
/* The residue of a CRC is what you get from the CRC over the
16037
* message catenated with its CRC. This is the post-final-xor
16138
* residue for CRC-32 (CRC-32/ISO-HDLC) which Zephyr calls
@@ -174,19 +51,13 @@ bool retained_validate(void)
17451
/* Reset to accrue runtime from this session. */
17552
retained.uptime_latest = 0;
17653

177-
/* Reconfigure to retain the state during system off, regardless of
178-
* whether validation succeeded. Although these values can sometimes
179-
* be observed to be preserved across System OFF, the product
180-
* specification states they are not retained in that situation, and
181-
* that can also be observed.
182-
*/
183-
(void)ram_range_retain(&retained, RETAINED_CHECKED_SIZE, true);
184-
18554
return valid;
18655
}
18756

18857
void retained_update(void)
18958
{
59+
int rc;
60+
19061
uint64_t now = k_uptime_ticks();
19162

19263
retained.uptime_sum += (now - retained.uptime_latest);
@@ -196,4 +67,7 @@ void retained_update(void)
19667
RETAINED_CRC_OFFSET);
19768

19869
retained.crc = sys_cpu_to_le32(crc);
70+
71+
rc = retained_mem_write(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained));
72+
__ASSERT_NO_MSG(rc == 0);
19973
}

0 commit comments

Comments
 (0)