Skip to content

Commit c769ef8

Browse files
committed
tests: benchmarks: multicore: Remote GDF switching
Add test cases for fast counter, pwm, spim, uarte instances where global domain frequency is changed from remote application. Use solution for synchronization of host and remote core like in idle_pwm_loopback case. Signed-off-by: Piotr Krzyzanowski <piotr.krzyzanowski@nordicsemi.no>
1 parent 4dfdc18 commit c769ef8

File tree

20 files changed

+314
-59
lines changed

20 files changed

+314
-59
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(remote_sleep_forever)
11+
12+
target_sources(app PRIVATE src/main.c)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
aliases {
9+
led = &led1;
10+
};
11+
12+
leds {
13+
compatible = "gpio-leds";
14+
led1: led_1 {
15+
gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>;
16+
label = "Green LED 1";
17+
};
18+
};
19+
};
20+
21+
&gpio9 {
22+
status = "okay";
23+
};
24+
25+
&gpiote130 {
26+
status = "okay";
27+
};
28+
29+
&uart135 {
30+
status = "disabled";
31+
/delete-property/memory-regions;
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CONFIG_CLOCK_CONTROL=y
2+
3+
CONFIG_PM=y
4+
CONFIG_POWEROFF=y
5+
CONFIG_CONSOLE=n
6+
CONFIG_UART_CONSOLE=n
7+
CONFIG_SERIAL=n
8+
CONFIG_GPIO=y
9+
CONFIG_BOOT_BANNER=n
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
#include <zephyr/cache.h>
7+
#include <zephyr/drivers/gpio.h>
8+
#include <zephyr/devicetree/clocks.h>
9+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
10+
#include <zephyr/kernel.h>
11+
12+
#define REMOTE_IS_READY (2)
13+
#define SHM_START_ADDR (DT_REG_ADDR(DT_NODELABEL(cpuapp_cpurad_ipc_shm)))
14+
volatile static uint32_t *shared_var = (volatile uint32_t *) SHM_START_ADDR;
15+
16+
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios);
17+
18+
const uint32_t freq[] = {320, 256, 128, 64};
19+
20+
/*
21+
* Set Global Domain frequency (HSFLL120)
22+
*/
23+
void set_global_domain_frequency(uint32_t freq)
24+
{
25+
int err;
26+
int res;
27+
struct onoff_client cli;
28+
const struct device *hsfll_dev = DEVICE_DT_GET(DT_NODELABEL(hsfll120));
29+
const struct nrf_clock_spec clk_spec_global_hsfll = {.frequency = MHZ(freq)};
30+
31+
printk("Requested frequency [Hz]: %d\n", clk_spec_global_hsfll.frequency);
32+
sys_notify_init_spinwait(&cli.notify);
33+
err = nrf_clock_control_request(hsfll_dev, &clk_spec_global_hsfll, &cli);
34+
__ASSERT((err >= 0 && err < 3), "Wrong nrf_clock_control_request return code");
35+
do {
36+
err = sys_notify_fetch_result(&cli.notify, &res);
37+
k_yield();
38+
} while (err == -EAGAIN);
39+
__ASSERT(err == 0, "Wrong clock control request return code");
40+
__ASSERT(res == 0, "Wrong clock control request response");
41+
}
42+
43+
int main(void)
44+
{
45+
uint32_t counter = 0;
46+
47+
gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
48+
49+
*shared_var = REMOTE_IS_READY;
50+
sys_cache_data_flush_range((void *) shared_var, sizeof(*shared_var));
51+
k_msleep(300);
52+
53+
while (1) {
54+
gpio_pin_set_dt(&led, 1);
55+
set_global_domain_frequency(freq[counter++ % ARRAY_SIZE(freq)]);
56+
k_busy_wait(1000);
57+
gpio_pin_set_dt(&led, 0);
58+
k_msleep(2000);
59+
}
60+
61+
return 0;
62+
}

tests/benchmarks/multicore/idle_counter/Kconfig

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ config TEST_SLEEP_DURATION_MS
1212
Based on the value of 'min-residency-us' specified for each power state defined in the DTS,
1313
core enters the lowest possible power state.
1414

15+
config GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING
16+
bool "Enable global domain frequency changing"
17+
select CLOCK_CONTROL
18+
1519
source "Kconfig.zephyr"

tests/benchmarks/multicore/idle_counter/prj.conf

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ CONFIG_PM=y
99
CONFIG_PM_S2RAM=y
1010
CONFIG_PM_S2RAM_CUSTOM_MARKING=y
1111
CONFIG_POWEROFF=y
12+
CONFIG_CONSOLE=n
13+
CONFIG_UART_CONSOLE=n
1214
CONFIG_SERIAL=n
1315
CONFIG_BOOT_BANNER=n
1416
CONFIG_LOG=n

tests/benchmarks/multicore/idle_counter/remote/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,15 @@ config TEST_SLEEP_DURATION_MS
1212
Based on the value of 'min-residency-us' specified for each power state defined in the DTS,
1313
core enters the lowest possible power state.
1414

15+
config TEST_ROLE_REMOTE
16+
bool "Execute test variant for Remote core"
17+
default y
18+
help
19+
KConfig used in synchronization phase.
20+
Set TEST_ROLE_REMOTE=y on core that shall synchronize with the Host core.
21+
22+
config GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING
23+
bool "Enable global domain frequency changing from remote"
24+
select CLOCK_CONTROL
25+
1526
source "Kconfig.zephyr"

tests/benchmarks/multicore/idle_counter/remote/prj.conf

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ CONFIG_CONSOLE=n
1414
CONFIG_UART_CONSOLE=n
1515
CONFIG_SERIAL=n
1616
CONFIG_BOOT_BANNER=n
17+
CONFIG_LOG=n
1718

1819
CONFIG_ASSERT=y

tests/benchmarks/multicore/idle_counter/src/main.c

+54-21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <zephyr/kernel.h>
8+
#include <zephyr/cache.h>
89
#include <zephyr/drivers/gpio.h>
910
#include <zephyr/drivers/counter.h>
1011
#include <zephyr/logging/log.h>
@@ -13,16 +14,21 @@
1314

1415
LOG_MODULE_REGISTER(idle_counter);
1516

17+
#define SHM_START_ADDR (DT_REG_ADDR(DT_NODELABEL(cpuapp_cpurad_ipc_shm)))
18+
volatile static uint32_t *shared_var = (volatile uint32_t *)SHM_START_ADDR;
19+
#define HOST_IS_READY (1)
20+
#define REMOTE_IS_READY (2)
21+
1622
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios);
1723

1824
#define ALARM_CHANNEL_ID (0)
1925
const struct device *const counter_dev = DEVICE_DT_GET(DT_ALIAS(counter));
2026

2127
static K_SEM_DEFINE(my_sem, 0, 1);
2228

23-
#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP)
2429
const uint32_t freq[] = {320, 256, 128, 64};
2530

31+
#if defined(CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING)
2632
/*
2733
* Set Global Domain frequency (HSFLL120)
2834
*/
@@ -45,12 +51,11 @@ void set_global_domain_frequency(uint32_t freq)
4551
__ASSERT(err == 0, "Wrong clock control request return code");
4652
__ASSERT(res == 0, "Wrong clock control request response");
4753
}
48-
#endif /* CONFIG_CLOCK_CONTROL && CONFIG_SOC_NRF54H20_CPUAPP */
54+
#endif /* CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING */
4955

5056
void counter_handler(const struct device *counter_dev, uint8_t chan_id, uint32_t ticks,
5157
void *user_data)
5258
{
53-
gpio_pin_set_dt(&led, 1);
5459
k_sem_give(&my_sem);
5560
counter_stop(counter_dev);
5661
}
@@ -92,6 +97,17 @@ void verify_timer(uint32_t start_time)
9297
"expected time to elapse is 1s");
9398
}
9499

100+
void sleep_with_state_indication(uint32_t sleep_duration_ms)
101+
{
102+
int ret;
103+
104+
ret = gpio_pin_set_dt(&led, 0);
105+
__ASSERT(ret == 0, "Unable to turn off LED");
106+
k_msleep(sleep_duration_ms);
107+
ret = gpio_pin_set_dt(&led, 1);
108+
__ASSERT(ret == 0, "Unable to turn on LED");
109+
}
110+
95111
int main(void)
96112
{
97113
uint32_t start_time;
@@ -106,28 +122,45 @@ int main(void)
106122
/* Wait a bit to solve NRFS request timeout issue. */
107123
k_msleep(500);
108124

109-
while (1) {
110-
ret = gpio_pin_set_dt(&led, 0);
111-
__ASSERT(ret == 0, "Unable to turn off LED");
112-
k_msleep(CONFIG_TEST_SLEEP_DURATION_MS);
113-
ret = gpio_pin_set_dt(&led, 1);
114-
__ASSERT(ret == 0, "Unable to turn on LED");
115-
k_busy_wait(100000);
125+
/* Synchronize Remote core with Host core */
126+
#if !defined(CONFIG_TEST_ROLE_REMOTE)
127+
LOG_DBG("HOST starts");
128+
*shared_var = HOST_IS_READY;
129+
sys_cache_data_flush_range((void *)shared_var, sizeof(*shared_var));
130+
LOG_DBG("HOST wrote HOST_IS_READY: %u", *shared_var);
131+
while (*shared_var != REMOTE_IS_READY) {
132+
sys_cache_data_invd_range((void *)shared_var, sizeof(*shared_var));
133+
LOG_DBG("shared_var is: %u", *shared_var);
134+
}
135+
LOG_DBG("HOST continues");
136+
#else
137+
LOG_DBG("REMOTE starts");
138+
while (*shared_var != HOST_IS_READY) {
139+
sys_cache_data_invd_range((void *)shared_var, sizeof(*shared_var));
140+
LOG_DBG("shared_var is: %u", *shared_var);
141+
}
142+
LOG_DBG("REMOTE found that HOST_IS_READY");
143+
*shared_var = REMOTE_IS_READY;
144+
sys_cache_data_flush_range((void *)shared_var, sizeof(*shared_var));
145+
LOG_DBG("REMOTE wrote REMOTE_IS_READY: %u", *shared_var);
146+
LOG_DBG("REMOTE continues");
147+
#endif
116148

117-
#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP)
118-
for (int i = 0; i <= ARRAY_SIZE(freq); i++) {
149+
while (1) {
150+
sleep_with_state_indication(CONFIG_TEST_SLEEP_DURATION_MS);
151+
for (int i = 0; i < ARRAY_SIZE(freq); i++) {
119152
start_time = start_timer(counter_dev);
120-
if (i) {
121-
set_global_domain_frequency(freq[i - 1]);
122-
}
153+
k_msleep(100);
154+
#if defined(CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING)
155+
sleep_with_state_indication(CONFIG_TEST_SLEEP_DURATION_MS / 2 - 100);
156+
set_global_domain_frequency(freq[(i + 1) % ARRAY_SIZE(freq)]);
157+
k_msleep(10);
158+
#endif /* CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING */
123159
verify_timer(start_time);
124-
k_busy_wait(100000);
125160
}
126-
#else
127-
start_time = start_timer(counter_dev);
128-
verify_timer(start_time);
129-
k_busy_wait(100000);
130-
#endif /* CONFIG_CLOCK_CONTROL && CONFIG_SOC_NRF54H20_CPUAPP */
161+
ret = gpio_pin_set_dt(&led, 1);
162+
__ASSERT(ret == 0, "Unable to turn on LED");
163+
k_msleep(100);
131164
}
132165

133166
return 0;

tests/benchmarks/multicore/idle_counter/sysbuild.cmake

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55
#
66

7-
# Add remote project
8-
ExternalZephyrProject_Add(
7+
if(SB_CONFIG_SOC_NRF54H20)
8+
# Add remote project
9+
ExternalZephyrProject_Add(
910
APPLICATION remote
10-
SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/tests/benchmarks/power_consumption/common/remote_sleep_forever
11+
SOURCE_DIR ${APP_DIR}/remote
1112
BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad
1213
BOARD_REVISION ${BOARD_REVISION}
13-
)
14+
)
15+
endif()
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
common:
2+
sysbuild: true
3+
integration_platforms:
4+
- nrf54h20dk/nrf54h20/cpuapp
5+
platform_allow:
6+
- nrf54h20dk/nrf54h20/cpuapp
27
tags:
38
- ppk_power_measure
49
- ci_tests_benchmarks_current_consumption
510
tests:
611
benchmarks.power_consumption.counter:
7-
sysbuild: true
8-
integration_platforms:
9-
- nrf54h20dk/nrf54h20/cpuapp
10-
platform_allow:
11-
- nrf54h20dk/nrf54h20/cpuapp
1212
extra_args:
13-
- CONFIG_CLOCK_CONTROL=y
13+
- idle_counter_CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING=y
1414
harness: pytest
1515
harness_config:
1616
fixture: ppk_power_measure
1717
pytest_root:
18-
- "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_fast_timer_and_s2ram_with_clock_control"
18+
- "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_fast_counter_and_s2ram_with_clock_control"
19+
20+
benchmarks.power_consumption.counter.remote_gd_freq_switching:
21+
extra_args:
22+
- remote_CONFIG_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING=y
23+
harness: pytest
24+
harness_config:
25+
fixture: ppk_power_measure
26+
pytest_root:
27+
- "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_fast_counter_and_s2ram_with_clock_control"

tests/benchmarks/multicore/idle_pwm_loopback/Kconfig.sysbuild

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66

77
source "${ZEPHYR_BASE}/share/sysbuild/Kconfig"
88

9-
config REMOTE_BOARD
10-
string
11-
default "$(BOARD)/nrf54h20/cpurad" if SOC_NRF54H20_CPUAPP
9+
config REMOTE_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING
10+
bool "Enable global domain frequency changing from remote"

tests/benchmarks/multicore/idle_pwm_loopback/sysbuild.cmake

+12-8
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55
#
66

7-
if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "")
8-
message(FATAL_ERROR "REMOTE_BOARD must be set to a valid board name")
9-
endif()
7+
if(SB_CONFIG_SOC_NRF54H20)
8+
if(SB_CONFIG_REMOTE_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING)
9+
set(REMOTE_SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/tests/benchmarks/multicore/common/remote_gdf_switching)
10+
else()
11+
set(REMOTE_SOURCE_DIR ${APP_DIR}/remote)
12+
endif()
1013

11-
# Add remote project
12-
ExternalZephyrProject_Add(
14+
# Add remote project
15+
ExternalZephyrProject_Add(
1316
APPLICATION remote
14-
SOURCE_DIR ${APP_DIR}/remote
15-
BOARD ${SB_CONFIG_REMOTE_BOARD}
17+
SOURCE_DIR ${REMOTE_SOURCE_DIR}
18+
BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad
1619
BOARD_REVISION ${BOARD_REVISION}
17-
)
20+
)
21+
endif()

tests/benchmarks/multicore/idle_pwm_loopback/testcase.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ tests:
9090
pytest_root:
9191
- "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_pwm_and_s2ram"
9292

93+
benchmarks.multicore.idle_pwm_loopback.nrf54h20dk_cpuapp_cpurad.s2ram_fast.remote_gd_freq_switching:
94+
filter: not CONFIG_COVERAGE
95+
tags: ppk_power_measure
96+
extra_args:
97+
- idle_pwm_loopback_CONF_FILE=prj_s2ram.conf
98+
- idle_pwm_loopback_DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_1.overlay"
99+
- SB_CONFIG_REMOTE_GLOBAL_DOMAIN_CLOCK_FREQUENCY_SWITCHING=y
100+
harness: pytest
101+
harness_config:
102+
fixture: spi_loopback
103+
pytest_root:
104+
- "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_pwm_and_s2ram"
105+
93106
benchmarks.multicore.idle_pwm_loopback.nrf54h20dk_cpuapp_cpurad.s2ram_fast.gd_freq_320MHz:
94107
filter: not CONFIG_COVERAGE
95108
tags: ppk_power_measure

0 commit comments

Comments
 (0)