From 567c4436a5309305094edacdd5a0d10306e2b5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Mon, 13 Jan 2025 12:58:28 +0100 Subject: [PATCH] tests: benchmarks: multicore: Add PM tests with FLPR core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test that confirms Power Management on FLPR core. Signed-off-by: Sebastian Głąb --- .../{idle_ppr/src => common}/power_off.c | 0 .../multicore/idle_flpr/CMakeLists.txt | 19 ++++ tests/benchmarks/multicore/idle_flpr/Kconfig | 15 +++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 27 ++++++ tests/benchmarks/multicore/idle_flpr/prj.conf | 8 ++ .../multicore/idle_flpr/prj_s2ram.conf | 18 ++++ .../multicore/idle_flpr/remote/CMakeLists.txt | 17 ++++ .../multicore/idle_flpr/remote/Kconfig | 21 +++++ .../nrf54h20dk_nrf54h20_cpuflpr.overlay | 29 ++++++ .../multicore/idle_flpr/remote/prj.conf | 11 +++ .../multicore/idle_flpr/remote/prj_s2ram.conf | 13 +++ .../multicore/idle_flpr/remote/src/main.c | 17 ++++ .../benchmarks/multicore/idle_flpr/src/main.c | 80 ++++++++++++++++ .../multicore/idle_flpr/sysbuild.cmake | 20 ++++ .../multicore/idle_flpr/testcase.yaml | 47 ++++++++++ .../multicore/idle_ppr/remote/CMakeLists.txt | 4 +- .../multicore/idle_stm/remote/CMakeLists.txt | 2 +- .../multicore/idle_stm/src/power_off.c | 94 ------------------- 18 files changed, 345 insertions(+), 97 deletions(-) rename tests/benchmarks/multicore/{idle_ppr/src => common}/power_off.c (100%) create mode 100644 tests/benchmarks/multicore/idle_flpr/CMakeLists.txt create mode 100644 tests/benchmarks/multicore/idle_flpr/Kconfig create mode 100644 tests/benchmarks/multicore/idle_flpr/boards/nrf54h20dk_nrf54h20_cpuapp.overlay create mode 100644 tests/benchmarks/multicore/idle_flpr/prj.conf create mode 100644 tests/benchmarks/multicore/idle_flpr/prj_s2ram.conf create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/CMakeLists.txt create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/Kconfig create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/prj.conf create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/prj_s2ram.conf create mode 100644 tests/benchmarks/multicore/idle_flpr/remote/src/main.c create mode 100644 tests/benchmarks/multicore/idle_flpr/src/main.c create mode 100644 tests/benchmarks/multicore/idle_flpr/sysbuild.cmake create mode 100644 tests/benchmarks/multicore/idle_flpr/testcase.yaml delete mode 100644 tests/benchmarks/multicore/idle_stm/src/power_off.c diff --git a/tests/benchmarks/multicore/idle_ppr/src/power_off.c b/tests/benchmarks/multicore/common/power_off.c similarity index 100% rename from tests/benchmarks/multicore/idle_ppr/src/power_off.c rename to tests/benchmarks/multicore/common/power_off.c diff --git a/tests/benchmarks/multicore/idle_flpr/CMakeLists.txt b/tests/benchmarks/multicore/idle_flpr/CMakeLists.txt new file mode 100644 index 000000000000..63972e468c76 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/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_flpr) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/benchmarks/multicore/idle_flpr/Kconfig b/tests/benchmarks/multicore/idle_flpr/Kconfig new file mode 100644 index 000000000000..b0f6610df57c --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/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_flpr/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/benchmarks/multicore/idle_flpr/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 000000000000..7f36251d6b49 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +&cpuflpr_vpr { + status = "okay"; +}; + +&uart120 { + status = "reserved"; + interrupt-parent = <&cpuflpr_clic>; +}; + +/ { + aliases { + /delete-property/ led1; + }; +}; + +/delete-node/ &led1; + +&gpiote130 { + status = "okay"; + owned-channels = <0>; +}; diff --git a/tests/benchmarks/multicore/idle_flpr/prj.conf b/tests/benchmarks/multicore/idle_flpr/prj.conf new file mode 100644 index 000000000000..dc1e777e2769 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/prj.conf @@ -0,0 +1,8 @@ +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n + +CONFIG_LOG=y +CONFIG_ASSERT=y +CONFIG_GPIO=y + +CONFIG_NRF_REGTOOL_VERBOSITY=1 diff --git a/tests/benchmarks/multicore/idle_flpr/prj_s2ram.conf b/tests/benchmarks/multicore/idle_flpr/prj_s2ram.conf new file mode 100644 index 000000000000..7dd7a80ee5fe --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/prj_s2ram.conf @@ -0,0 +1,18 @@ +CONFIG_PM=y +CONFIG_PM_S2RAM=y +CONFIG_PM_S2RAM_CUSTOM_MARKING=y +CONFIG_POWEROFF=y + +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y + +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_PRINTK=n +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n + +CONFIG_ASSERT=y +CONFIG_GPIO=y diff --git a/tests/benchmarks/multicore/idle_flpr/remote/CMakeLists.txt b/tests/benchmarks/multicore/idle_flpr/remote/CMakeLists.txt new file mode 100644 index 000000000000..4fce15b9415c --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# 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) + +if((DEFINED CONFIG_SOC_NRF54H20_CPUFLPR) OR (DEFINED CONFIG_SOC_NRF54H20_ENGB_CPUFLPR)) + message(STATUS "Power Mode handler for RISC V is included.") + target_sources(app PRIVATE ../../common/power_off.c) +endif() diff --git a/tests/benchmarks/multicore/idle_flpr/remote/Kconfig b/tests/benchmarks/multicore/idle_flpr/remote/Kconfig new file mode 100644 index 000000000000..f33496efced0 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/Kconfig @@ -0,0 +1,21 @@ +# +# 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. + +config APP_PROVIDE_PM_HOOKS + bool "Application provides PM hooks" + default y + select HAS_PM + select HAS_POWEROFF + +source "Kconfig.zephyr" diff --git a/tests/benchmarks/multicore/idle_flpr/remote/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay b/tests/benchmarks/multicore/idle_flpr/remote/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay new file mode 100644 index 000000000000..d255f15e3a9b --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + cpus { + power-states { + wait: wait { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + substate-id = <0>; + min-residency-us = <20000>; + }; + + hibernate: hibernate { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + substate-id = <0>; + min-residency-us = <400000>; + }; + }; + }; +}; + +&cpu { + cpu-power-states = <&wait &hibernate>; +}; diff --git a/tests/benchmarks/multicore/idle_flpr/remote/prj.conf b/tests/benchmarks/multicore/idle_flpr/remote/prj.conf new file mode 100644 index 000000000000..f12c630cd503 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/prj.conf @@ -0,0 +1,11 @@ +CONFIG_LOG=y +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_PRINTK=n + +CONFIG_ASSERT=y + +CONFIG_NRF_REGTOOL_VERBOSITY=1 diff --git a/tests/benchmarks/multicore/idle_flpr/remote/prj_s2ram.conf b/tests/benchmarks/multicore/idle_flpr/remote/prj_s2ram.conf new file mode 100644 index 000000000000..06ba0a25e575 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/prj_s2ram.conf @@ -0,0 +1,13 @@ +CONFIG_PM=y +CONFIG_POWEROFF=y + +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=y + +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n + +CONFIG_ASSERT=y diff --git a/tests/benchmarks/multicore/idle_flpr/remote/src/main.c b/tests/benchmarks/multicore/idle_flpr/remote/src/main.c new file mode 100644 index 000000000000..fbeee9eaba05 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/remote/src/main.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include + +#include +LOG_MODULE_REGISTER(idle_flpr, LOG_LEVEL_INF); + +int main(void) +{ + LOG_INF("Multicore idle_flpr test on %s", CONFIG_BOARD_TARGET); + LOG_INF("Main sleeps for %d ms", CONFIG_TEST_SLEEP_DURATION_MS); + + return 0; +} diff --git a/tests/benchmarks/multicore/idle_flpr/src/main.c b/tests/benchmarks/multicore/idle_flpr/src/main.c new file mode 100644 index 000000000000..f2f0ffb441ae --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/src/main.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include + +#include +LOG_MODULE_REGISTER(idle_flpr, LOG_LEVEL_INF); + +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + +/* Variables used to make CPU active for ~1 second */ +static struct k_timer my_timer; +static bool timer_expired; + +void my_timer_handler(struct k_timer *dummy) +{ + timer_expired = true; +} + +int main(void) +{ + int counter = 0; + int ret; + + LOG_INF("Multicore idle_flpr test on %s", CONFIG_BOARD_TARGET); + LOG_INF("Main sleeps for %d ms", CONFIG_TEST_SLEEP_DURATION_MS); + + ret = gpio_is_ready_dt(&led); + if (!ret) { + LOG_ERR("LED is not ready"); + } + __ASSERT(ret, "LED is not ready\n"); + + ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Unable to configure GPIO as output"); + } + __ASSERT(ret == 0, "Unable to configure GPIO as output\n"); + + k_timer_init(&my_timer, my_timer_handler, NULL); + + /* Run test forever */ + while (1) { + timer_expired = false; + + /* start a one-shot timer that expires after 1 second */ + k_timer_start(&my_timer, K_MSEC(1000), K_NO_WAIT); + + /* Turn ON LED */ + ret = gpio_pin_set_dt(&led, 1); + if (ret < 0) { + LOG_ERR("Unable to turn on LED"); + } + __ASSERT(ret == 0, "Unable to turn on LED\n"); + + /* Keep CPU active for ~ 1 second */ + while (!timer_expired) { + k_busy_wait(10000); + k_yield(); + } + + /* Turn OFF LED */ + ret = gpio_pin_set_dt(&led, 0); + if (ret < 0) { + LOG_ERR("Unable to turn off LED"); + } + __ASSERT(ret == 0, "Unable to turn off LED\n"); + + LOG_INF("Run %d", counter); + counter++; + + /* Sleep / enter low power state */ + k_msleep(CONFIG_TEST_SLEEP_DURATION_MS); + } + + return 0; +} diff --git a/tests/benchmarks/multicore/idle_flpr/sysbuild.cmake b/tests/benchmarks/multicore/idle_flpr/sysbuild.cmake new file mode 100644 index 000000000000..507cac537ade --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/sysbuild.cmake @@ -0,0 +1,20 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Add remote project +ExternalZephyrProject_Add( + APPLICATION remote_rad + SOURCE_DIR ${SYSBUILD_NRF_MODULE_DIR}/tests/benchmarks/power_consumption/common/remote_sleep_forever + BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad + BOARD_REVISION ${BOARD_REVISION} +) + +ExternalZephyrProject_Add( + APPLICATION remote_flpr + SOURCE_DIR ${APP_DIR}/remote + BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpuflpr + BOARD_REVISION ${BOARD_REVISION} +) diff --git a/tests/benchmarks/multicore/idle_flpr/testcase.yaml b/tests/benchmarks/multicore/idle_flpr/testcase.yaml new file mode 100644 index 000000000000..7d5f23f8ed88 --- /dev/null +++ b/tests/benchmarks/multicore/idle_flpr/testcase.yaml @@ -0,0 +1,47 @@ +common: + sysbuild: true + tags: + - ci_build + - ci_tests_benchmarks_multicore + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + integration_platforms: + - nrf54h20dk/nrf54h20/cpuapp + +tests: + benchmarks.multicore.idle_flpr.no_sleep: + required_snippets: + - nordic-log-stm + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "app/idle_flpr: Multicore idle_flpr test on" + - "flpr/idle_flpr: Multicore idle_flpr test on" + - "idle_flpr: Run 0" + - "idle_flpr: Run 1" + + benchmarks.multicore.idle_flpr.idle: + tags: ppk_power_measure + extra_args: + - idle_flpr_CONF_FILE=prj_s2ram.conf + - remote_flpr_CONF_FILE=prj_s2ram.conf + - idle_flpr_CONFIG_TEST_SLEEP_DURATION_MS=500 + - remote_flpr_CONFIG_TEST_SLEEP_DURATION_MS=500 + harness: pytest + harness_config: + fixture: ppk_power_measure + pytest_root: + - "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_ppr_and_idle" + + benchmarks.multicore.idle_flpr.s2ram: + tags: ppk_power_measure + extra_args: + - idle_flpr_CONF_FILE=prj_s2ram.conf + - remote_flpr_CONF_FILE=prj_s2ram.conf + harness: pytest + harness_config: + fixture: ppk_power_measure + pytest_root: + - "${CUSTOM_ROOT_TEST_DIR}/test_measure_power_consumption.py::test_measure_and_data_dump_ppr_and_s2ram" diff --git a/tests/benchmarks/multicore/idle_ppr/remote/CMakeLists.txt b/tests/benchmarks/multicore/idle_ppr/remote/CMakeLists.txt index 8c7890999fb9..3f38a9d2b32e 100644 --- a/tests/benchmarks/multicore/idle_ppr/remote/CMakeLists.txt +++ b/tests/benchmarks/multicore/idle_ppr/remote/CMakeLists.txt @@ -11,7 +11,7 @@ project(remote) target_sources(app PRIVATE ../src/main.c) -if(DEFINED CONFIG_SOC_NRF54H20_CPUPPR) +if((DEFINED CONFIG_SOC_NRF54H20_CPUPPR) OR (DEFINED CONFIG_SOC_NRF54H20_ENGB_CPUPPR)) message(STATUS "Power Mode handler for RISC V is included.") - target_sources(app PRIVATE ../src/power_off.c) + target_sources(app PRIVATE ../../common/power_off.c) endif() diff --git a/tests/benchmarks/multicore/idle_stm/remote/CMakeLists.txt b/tests/benchmarks/multicore/idle_stm/remote/CMakeLists.txt index 5fdde2d6d284..3f38a9d2b32e 100644 --- a/tests/benchmarks/multicore/idle_stm/remote/CMakeLists.txt +++ b/tests/benchmarks/multicore/idle_stm/remote/CMakeLists.txt @@ -13,5 +13,5 @@ target_sources(app PRIVATE ../src/main.c) if((DEFINED CONFIG_SOC_NRF54H20_CPUPPR) OR (DEFINED CONFIG_SOC_NRF54H20_ENGB_CPUPPR)) message(STATUS "Power Mode handler for RISC V is included.") - target_sources(app PRIVATE ../src/power_off.c) + target_sources(app PRIVATE ../../common/power_off.c) endif() diff --git a/tests/benchmarks/multicore/idle_stm/src/power_off.c b/tests/benchmarks/multicore/idle_stm/src/power_off.c deleted file mode 100644 index 50cfbf7d226f..000000000000 --- a/tests/benchmarks/multicore/idle_stm/src/power_off.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ -#include -#include -#include -#include - -#include -LOG_MODULE_REGISTER(power_off, LOG_LEVEL_INF); - -#define VIPER_SLEEP_SUBSTATE_WAIT 0 -#define VIPER_SLEEP_SUBSTATE_SLEEP 1 -#define VIPER_SLEEP_SUBSTATE_HIBERNATE 0 -#define VIPER_SLEEP_SUBSTATE_DEEPSLEEP 1 - -static void pm_go_to_wait(void) -{ - LOG_INF("Wait Sleep State"); - - csr_write(VPRCSR_NORDIC_VPRNORDICSLEEPCTRL, - VPRCSR_NORDIC_VPRNORDICSLEEPCTRL_SLEEPSTATE_WAIT); - nrf_barrier_w(); - arch_cpu_idle(); -} - -static void pm_go_to_hibernate(void) -{ - LOG_INF("Hibernate Sleep State"); - - csr_write(VPRCSR_NORDIC_VPRNORDICSLEEPCTRL, - VPRCSR_NORDIC_VPRNORDICSLEEPCTRL_SLEEPSTATE_HIBERNATE); - nrf_barrier_w(); - arch_cpu_idle(); -} - -/** - * @brief Zephyr callback function to set/enter new PM State - * - * @param state Current PM State - * @param substate_id Substate of current PM State - */ -void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - LOG_INF("PPR pm_state_set: %d\t%d", (int)state, (int)substate_id); - - switch (state) { - case PM_STATE_SUSPEND_TO_RAM: { - switch (substate_id) { - case VIPER_SLEEP_SUBSTATE_HIBERNATE: - pm_go_to_hibernate(); - break; - case VIPER_SLEEP_SUBSTATE_DEEPSLEEP: - /* do nothing */ - break; - } - } break; - case PM_STATE_STANDBY: { - switch (substate_id) { - case VIPER_SLEEP_SUBSTATE_WAIT: - pm_go_to_wait(); - break; - } - } break; - case PM_STATE_SUSPEND_TO_IDLE: - case PM_STATE_SUSPEND_TO_DISK: - case PM_STATE_SOFT_OFF: - case PM_STATE_COUNT: - case PM_STATE_ACTIVE: - case PM_STATE_RUNTIME_IDLE: - break; - } -} - -/** - * @brief Zephyr callback function to exit current PM State - * - * @param state Current PM State - * @param substate_id Substate of current PM State - * - */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) -{ - LOG_INF("PPR pm_state_exit_post_ops"); - ARG_UNUSED(substate_id); - - csr_write(VPRCSR_NORDIC_VPRNORDICSLEEPCTRL, - VPRCSR_NORDIC_VPRNORDICSLEEPCTRL_SLEEPSTATE_WAIT); - - /* unlock interrupts after sleep */ - irq_unlock(MSTATUS_IEN); -}