Skip to content

Commit 50601fe

Browse files
nordic-pikrnordic-piks
authored andcommitted
tests: benchmarks: multicore: Add idle_counter
Add test to validate fast TIMER operation Signed-off-by: Piotr Krzyzanowski <[email protected]>
1 parent 83b373b commit 50601fe

File tree

11 files changed

+313
-0
lines changed

11 files changed

+313
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
11+
if(NOT SYSBUILD)
12+
message(FATAL_ERROR
13+
" This is a multi-image application that should be built using sysbuild.\n"
14+
" Add --sysbuild argument to west build command to prepare all the images.")
15+
endif()
16+
17+
project(idle_counter)
18+
19+
target_sources(app PRIVATE src/main.c)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
config TEST_SLEEP_DURATION_MS
8+
int "Core sleep duration (miliseconds)"
9+
default 1000
10+
help
11+
Set sleep duration to TEST_SLEEP_DURATION_MS miliseconds.
12+
Based on the value of 'min-residency-us' specified for each power state defined in the DTS,
13+
core enters the lowest possible power state.
14+
15+
source "Kconfig.zephyr"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
aliases {
9+
led = &led0;
10+
/delete-property/ led1;
11+
counter = &timer120;
12+
};
13+
};
14+
15+
&timer120 {
16+
status = "okay";
17+
};
18+
19+
/delete-node/ &led1;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Drivers and peripherals
2+
CONFIG_COUNTER=y
3+
4+
# Enable runtime power management for peripheral
5+
CONFIG_PM_DEVICE=y
6+
CONFIG_PM_DEVICE_RUNTIME=y
7+
8+
CONFIG_PM=y
9+
CONFIG_PM_S2RAM=y
10+
CONFIG_PM_S2RAM_CUSTOM_MARKING=y
11+
CONFIG_POWEROFF=y
12+
CONFIG_SERIAL=n
13+
CONFIG_BOOT_BANNER=n
14+
CONFIG_LOG=n
15+
16+
CONFIG_ASSERT=y
Lines changed: 12 additions & 0 deletions
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)
11+
12+
target_sources(app PRIVATE ../src/main.c)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
config TEST_SLEEP_DURATION_MS
8+
int "Core sleep duration (miliseconds)"
9+
default 1000
10+
help
11+
Set sleep duration to TEST_SLEEP_DURATION_MS miliseconds.
12+
Based on the value of 'min-residency-us' specified for each power state defined in the DTS,
13+
core enters the lowest possible power state.
14+
15+
source "Kconfig.zephyr"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>
8+
9+
/ {
10+
aliases {
11+
led = &led1;
12+
counter = &timer130;
13+
};
14+
15+
leds {
16+
compatible = "gpio-leds";
17+
led1: led_1 {
18+
gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>;
19+
label = "Green LED 1";
20+
};
21+
};
22+
};
23+
24+
&gpio9 {
25+
status = "okay";
26+
};
27+
28+
&gpiote130 {
29+
status = "okay";
30+
};
31+
32+
&timer130 {
33+
status = "okay";
34+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Drivers and peripherals
2+
CONFIG_COUNTER=y
3+
CONFIG_GPIO=y
4+
5+
# Enable runtime power management for peripheral
6+
CONFIG_PM_DEVICE=y
7+
CONFIG_PM_DEVICE_RUNTIME=y
8+
9+
CONFIG_PM=y
10+
CONFIG_PM_S2RAM=y
11+
CONFIG_PM_S2RAM_CUSTOM_MARKING=y
12+
CONFIG_POWEROFF=y
13+
CONFIG_CONSOLE=n
14+
CONFIG_UART_CONSOLE=n
15+
CONFIG_SERIAL=n
16+
CONFIG_BOOT_BANNER=n
17+
18+
CONFIG_ASSERT=y
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/drivers/gpio.h>
9+
#include <zephyr/drivers/counter.h>
10+
#include <zephyr/logging/log.h>
11+
#include <zephyr/devicetree/clocks.h>
12+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
13+
14+
LOG_MODULE_REGISTER(idle_counter);
15+
16+
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios);
17+
18+
#define ALARM_CHANNEL_ID (0)
19+
const struct device *const counter_dev = DEVICE_DT_GET(DT_ALIAS(counter));
20+
21+
static K_SEM_DEFINE(my_sem, 0, 1);
22+
23+
#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP)
24+
const uint32_t freq[] = {320, 256, 128, 64};
25+
26+
/*
27+
* Set Global Domain frequency (HSFLL120)
28+
*/
29+
void set_global_domain_frequency(uint32_t freq)
30+
{
31+
int err;
32+
int res;
33+
struct onoff_client cli;
34+
const struct device *hsfll_dev = DEVICE_DT_GET(DT_NODELABEL(hsfll120));
35+
const struct nrf_clock_spec clk_spec_global_hsfll = {.frequency = MHZ(freq)};
36+
37+
LOG_INF("Requested frequency [Hz]: %d", clk_spec_global_hsfll.frequency);
38+
sys_notify_init_spinwait(&cli.notify);
39+
err = nrf_clock_control_request(hsfll_dev, &clk_spec_global_hsfll, &cli);
40+
__ASSERT((err >= 0 && err < 3), "Wrong nrf_clock_control_request return code");
41+
do {
42+
err = sys_notify_fetch_result(&cli.notify, &res);
43+
k_yield();
44+
} while (err == -EAGAIN);
45+
__ASSERT(err == 0, "Wrong clock control request return code");
46+
__ASSERT(res == 0, "Wrong clock control request response");
47+
}
48+
#endif /* CONFIG_CLOCK_CONTROL && CONFIG_SOC_NRF54H20_CPUAPP */
49+
50+
void counter_handler(const struct device *counter_dev, uint8_t chan_id, uint32_t ticks,
51+
void *user_data)
52+
{
53+
gpio_pin_set_dt(&led, 1);
54+
k_sem_give(&my_sem);
55+
counter_stop(counter_dev);
56+
}
57+
58+
uint32_t start_timer(const struct device *counter_dev)
59+
{
60+
uint32_t start_time;
61+
struct counter_alarm_cfg counter_cfg;
62+
63+
counter_cfg.flags = 0;
64+
counter_cfg.ticks = counter_us_to_ticks(counter_dev, CONFIG_TEST_SLEEP_DURATION_MS * 1000);
65+
counter_cfg.callback = counter_handler;
66+
counter_cfg.user_data = &counter_cfg;
67+
counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID, &counter_cfg);
68+
69+
counter_start(counter_dev);
70+
start_time = k_cycle_get_32();
71+
72+
LOG_INF("Counter starts at %u cycle", start_time);
73+
74+
return start_time;
75+
}
76+
77+
void verify_timer(uint32_t start_time)
78+
{
79+
uint32_t elapsed;
80+
int ret;
81+
82+
ret = gpio_pin_set_dt(&led, 0);
83+
__ASSERT(ret == 0, "Unable to turn off LED");
84+
ret = k_sem_take(&my_sem, K_MSEC(CONFIG_TEST_SLEEP_DURATION_MS + 100));
85+
elapsed = k_cycle_get_32() - start_time;
86+
__ASSERT(ret == 0, "Timer callback not called");
87+
ret = gpio_pin_set_dt(&led, 1);
88+
__ASSERT(ret == 0, "Unable to turn on LED");
89+
LOG_INF("Elapsed %u cycles (%uus)", elapsed, k_cyc_to_us_ceil32(elapsed));
90+
__ASSERT(elapsed > k_ms_to_cyc_ceil32(CONFIG_TEST_SLEEP_DURATION_MS - 10) &&
91+
elapsed < k_ms_to_cyc_ceil32(CONFIG_TEST_SLEEP_DURATION_MS + 10),
92+
"expected time to elapse is 1s");
93+
}
94+
95+
int main(void)
96+
{
97+
uint32_t start_time;
98+
int ret;
99+
100+
ret = gpio_is_ready_dt(&led);
101+
__ASSERT(ret, "Error: GPIO Device not ready");
102+
103+
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
104+
__ASSERT(ret == 0, "Could not configure led GPIO");
105+
106+
/* Wait a bit to solve NRFS request timeout issue. */
107+
k_msleep(500);
108+
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);
116+
117+
#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP)
118+
for (int i = 0; i <= ARRAY_SIZE(freq); i++) {
119+
start_time = start_timer(counter_dev);
120+
if (i) {
121+
set_global_domain_frequency(freq[i - 1]);
122+
}
123+
verify_timer(start_time);
124+
k_busy_wait(100000);
125+
}
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 */
131+
}
132+
133+
return 0;
134+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# Add remote project
8+
ExternalZephyrProject_Add(
9+
APPLICATION remote
10+
SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/tests/benchmarks/power_consumption/common/remote_sleep_forever
11+
BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad
12+
BOARD_REVISION ${BOARD_REVISION}
13+
)

0 commit comments

Comments
 (0)