From fc4da54c4f2e319e67aa4569125ba652d05a4648 Mon Sep 17 00:00:00 2001 From: Piotr Krzyzanowski Date: Sun, 19 Jan 2025 21:18:57 +0100 Subject: [PATCH] tests: benchmarks: multicore: Add idle_counter Add test to validate fast TIMER operation Signed-off-by: Piotr Krzyzanowski --- .../multicore/idle_counter/CMakeLists.txt | 19 +++ .../benchmarks/multicore/idle_counter/Kconfig | 15 ++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 19 +++ .../multicore/idle_counter/prj.conf | 16 +++ .../idle_counter/remote/CMakeLists.txt | 12 ++ .../multicore/idle_counter/remote/Kconfig | 15 ++ .../boards/nrf54h20dk_nrf54h20_cpurad.overlay | 34 +++++ .../multicore/idle_counter/remote/prj.conf | 18 +++ .../multicore/idle_counter/src/main.c | 134 ++++++++++++++++++ .../multicore/idle_counter/sysbuild.cmake | 13 ++ .../multicore/idle_counter/testcase.yaml | 18 +++ 11 files changed, 313 insertions(+) create mode 100644 tests/benchmarks/multicore/idle_counter/CMakeLists.txt create mode 100644 tests/benchmarks/multicore/idle_counter/Kconfig create mode 100644 tests/benchmarks/multicore/idle_counter/boards/nrf54h20dk_nrf54h20_cpuapp.overlay create mode 100644 tests/benchmarks/multicore/idle_counter/prj.conf create mode 100644 tests/benchmarks/multicore/idle_counter/remote/CMakeLists.txt create mode 100644 tests/benchmarks/multicore/idle_counter/remote/Kconfig create mode 100644 tests/benchmarks/multicore/idle_counter/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay create mode 100644 tests/benchmarks/multicore/idle_counter/remote/prj.conf create mode 100644 tests/benchmarks/multicore/idle_counter/src/main.c create mode 100644 tests/benchmarks/multicore/idle_counter/sysbuild.cmake create mode 100644 tests/benchmarks/multicore/idle_counter/testcase.yaml diff --git a/tests/benchmarks/multicore/idle_counter/CMakeLists.txt b/tests/benchmarks/multicore/idle_counter/CMakeLists.txt new file mode 100644 index 000000000000..ec72d0299694 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +if(NOT SYSBUILD) + message(FATAL_ERROR + " This is a multi-image application that should be built using sysbuild.\n" + " Add --sysbuild argument to west build command to prepare all the images.") +endif() + +project(idle_counter) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/benchmarks/multicore/idle_counter/Kconfig b/tests/benchmarks/multicore/idle_counter/Kconfig new file mode 100644 index 000000000000..b0f6610df57c --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/Kconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config TEST_SLEEP_DURATION_MS + int "Core sleep duration (miliseconds)" + default 1000 + help + Set sleep duration to TEST_SLEEP_DURATION_MS miliseconds. + Based on the value of 'min-residency-us' specified for each power state defined in the DTS, + core enters the lowest possible power state. + +source "Kconfig.zephyr" diff --git a/tests/benchmarks/multicore/idle_counter/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/benchmarks/multicore/idle_counter/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..d344e1dcdd00 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + aliases { + led = &led0; + /delete-property/ led1; + counter = &timer120; + }; +}; + +&timer120 { + status = "okay"; +}; + +/delete-node/ &led1; diff --git a/tests/benchmarks/multicore/idle_counter/prj.conf b/tests/benchmarks/multicore/idle_counter/prj.conf new file mode 100644 index 000000000000..05692a7c3087 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/prj.conf @@ -0,0 +1,16 @@ +# Drivers and peripherals +CONFIG_COUNTER=y + +# Enable runtime power management for peripheral +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y + +CONFIG_PM=y +CONFIG_PM_S2RAM=y +CONFIG_PM_S2RAM_CUSTOM_MARKING=y +CONFIG_POWEROFF=y +CONFIG_SERIAL=n +CONFIG_BOOT_BANNER=n +CONFIG_LOG=n + +CONFIG_ASSERT=y diff --git a/tests/benchmarks/multicore/idle_counter/remote/CMakeLists.txt b/tests/benchmarks/multicore/idle_counter/remote/CMakeLists.txt new file mode 100644 index 000000000000..fc2ee33a0797 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/remote/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(remote) + +target_sources(app PRIVATE ../src/main.c) diff --git a/tests/benchmarks/multicore/idle_counter/remote/Kconfig b/tests/benchmarks/multicore/idle_counter/remote/Kconfig new file mode 100644 index 000000000000..b0f6610df57c --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/remote/Kconfig @@ -0,0 +1,15 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config TEST_SLEEP_DURATION_MS + int "Core sleep duration (miliseconds)" + default 1000 + help + Set sleep duration to TEST_SLEEP_DURATION_MS miliseconds. + Based on the value of 'min-residency-us' specified for each power state defined in the DTS, + core enters the lowest possible power state. + +source "Kconfig.zephyr" diff --git a/tests/benchmarks/multicore/idle_counter/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/tests/benchmarks/multicore/idle_counter/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay new file mode 100644 index 000000000000..d93c47d4183e --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include + +/ { + aliases { + led = &led1; + counter = &timer130; + }; + + leds { + compatible = "gpio-leds"; + led1: led_1 { + gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + }; +}; + +&gpio9 { + status = "okay"; +}; + +&gpiote130 { + status = "okay"; +}; + +&timer130 { + status = "okay"; +}; diff --git a/tests/benchmarks/multicore/idle_counter/remote/prj.conf b/tests/benchmarks/multicore/idle_counter/remote/prj.conf new file mode 100644 index 000000000000..810e3c575e78 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/remote/prj.conf @@ -0,0 +1,18 @@ +# Drivers and peripherals +CONFIG_COUNTER=y +CONFIG_GPIO=y + +# Enable runtime power management for peripheral +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y + +CONFIG_PM=y +CONFIG_PM_S2RAM=y +CONFIG_PM_S2RAM_CUSTOM_MARKING=y +CONFIG_POWEROFF=y +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_BOOT_BANNER=n + +CONFIG_ASSERT=y diff --git a/tests/benchmarks/multicore/idle_counter/src/main.c b/tests/benchmarks/multicore/idle_counter/src/main.c new file mode 100644 index 000000000000..be6342eb5415 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/src/main.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(idle_counter); + +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios); + +#define ALARM_CHANNEL_ID (0) +const struct device *const counter_dev = DEVICE_DT_GET(DT_ALIAS(counter)); + +static K_SEM_DEFINE(my_sem, 0, 1); + +#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP) +const uint32_t freq[] = {320, 256, 128, 64}; + +/* + * Set Global Domain frequency (HSFLL120) + */ +void set_global_domain_frequency(uint32_t freq) +{ + int err; + int res; + struct onoff_client cli; + const struct device *hsfll_dev = DEVICE_DT_GET(DT_NODELABEL(hsfll120)); + const struct nrf_clock_spec clk_spec_global_hsfll = {.frequency = MHZ(freq)}; + + LOG_INF("Requested frequency [Hz]: %d", clk_spec_global_hsfll.frequency); + sys_notify_init_spinwait(&cli.notify); + err = nrf_clock_control_request(hsfll_dev, &clk_spec_global_hsfll, &cli); + __ASSERT((err >= 0 && err < 3), "Wrong nrf_clock_control_request return code"); + do { + err = sys_notify_fetch_result(&cli.notify, &res); + k_yield(); + } while (err == -EAGAIN); + __ASSERT(err == 0, "Wrong clock control request return code"); + __ASSERT(res == 0, "Wrong clock control request response"); +} +#endif /* CONFIG_CLOCK_CONTROL && CONFIG_SOC_NRF54H20_CPUAPP */ + +void counter_handler(const struct device *counter_dev, uint8_t chan_id, uint32_t ticks, + void *user_data) +{ + gpio_pin_set_dt(&led, 1); + k_sem_give(&my_sem); + counter_stop(counter_dev); +} + +uint32_t start_timer(const struct device *counter_dev) +{ + uint32_t start_time; + struct counter_alarm_cfg counter_cfg; + + counter_cfg.flags = 0; + counter_cfg.ticks = counter_us_to_ticks(counter_dev, CONFIG_TEST_SLEEP_DURATION_MS * 1000); + counter_cfg.callback = counter_handler; + counter_cfg.user_data = &counter_cfg; + counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID, &counter_cfg); + + counter_start(counter_dev); + start_time = k_cycle_get_32(); + + LOG_INF("Counter starts at %u cycle", start_time); + + return start_time; +} + +void verify_timer(uint32_t start_time) +{ + uint32_t elapsed; + int ret; + + ret = gpio_pin_set_dt(&led, 0); + __ASSERT(ret == 0, "Unable to turn off LED"); + ret = k_sem_take(&my_sem, K_MSEC(CONFIG_TEST_SLEEP_DURATION_MS + 100)); + elapsed = k_cycle_get_32() - start_time; + __ASSERT(ret == 0, "Timer callback not called"); + ret = gpio_pin_set_dt(&led, 1); + __ASSERT(ret == 0, "Unable to turn on LED"); + LOG_INF("Elapsed %u cycles (%uus)", elapsed, k_cyc_to_us_ceil32(elapsed)); + __ASSERT(elapsed > k_ms_to_cyc_ceil32(CONFIG_TEST_SLEEP_DURATION_MS - 10) && + elapsed < k_ms_to_cyc_ceil32(CONFIG_TEST_SLEEP_DURATION_MS + 10), + "expected time to elapse is 1s"); +} + +int main(void) +{ + uint32_t start_time; + int ret; + + ret = gpio_is_ready_dt(&led); + __ASSERT(ret, "Error: GPIO Device not ready"); + + ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); + __ASSERT(ret == 0, "Could not configure led GPIO"); + + /* Wait a bit to solve NRFS request timeout issue. */ + k_msleep(500); + + while (1) { + ret = gpio_pin_set_dt(&led, 0); + __ASSERT(ret == 0, "Unable to turn off LED"); + k_msleep(CONFIG_TEST_SLEEP_DURATION_MS); + ret = gpio_pin_set_dt(&led, 1); + __ASSERT(ret == 0, "Unable to turn on LED"); + k_busy_wait(100000); + +#if defined(CONFIG_CLOCK_CONTROL) && defined(CONFIG_SOC_NRF54H20_CPUAPP) + for (int i = 0; i <= ARRAY_SIZE(freq); i++) { + start_time = start_timer(counter_dev); + if (i) { + set_global_domain_frequency(freq[i - 1]); + } + verify_timer(start_time); + k_busy_wait(100000); + } +#else + start_time = start_timer(counter_dev); + verify_timer(start_time); + k_busy_wait(100000); +#endif /* CONFIG_CLOCK_CONTROL && CONFIG_SOC_NRF54H20_CPUAPP */ + } + + return 0; +} diff --git a/tests/benchmarks/multicore/idle_counter/sysbuild.cmake b/tests/benchmarks/multicore/idle_counter/sysbuild.cmake new file mode 100644 index 000000000000..0c96ea5e94b6 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/sysbuild.cmake @@ -0,0 +1,13 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Add remote project +ExternalZephyrProject_Add( + APPLICATION remote + SOURCE_DIR ${ZEPHYR_NRF_MODULE_DIR}/tests/benchmarks/power_consumption/common/remote_sleep_forever + BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad + BOARD_REVISION ${BOARD_REVISION} +) diff --git a/tests/benchmarks/multicore/idle_counter/testcase.yaml b/tests/benchmarks/multicore/idle_counter/testcase.yaml new file mode 100644 index 000000000000..d284622043b3 --- /dev/null +++ b/tests/benchmarks/multicore/idle_counter/testcase.yaml @@ -0,0 +1,18 @@ +common: + tags: + - ppk_power_measure + - ci_tests_benchmarks_current_consumption +tests: + benchmarks.power_consumption.counter: + sysbuild: true + integration_platforms: + - nrf54h20dk/nrf54h20/cpuapp + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + extra_args: + - CONFIG_CLOCK_CONTROL=y + harness: pytest + harness_config: + fixture: ppk_power_measure + pytest_root: + - "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_fast_timer_and_s2ram_with_clock_control"