Skip to content

Commit

Permalink
tests: benchmarks: multicore: Add PM tests with FLPR core
Browse files Browse the repository at this point in the history
Add test that confirms Power Management on FLPR core.

Signed-off-by: Sebastian Głąb <[email protected]>
  • Loading branch information
nordic-segl committed Jan 13, 2025
1 parent 6586628 commit 183e19e
Show file tree
Hide file tree
Showing 15 changed files with 464 additions and 0 deletions.
19 changes: 19 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# Copyright (c) 2024 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)
15 changes: 15 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2024 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"
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2024 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>;
};
8 changes: 8 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/prj.conf
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/prj_s2ram.conf
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# Copyright (c) 2024 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)
target_sources(app PRIVATE src/power_off.c)
message(STATUS "Power Mode handler for RISC V is included.")
21 changes: 21 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# Copyright (c) 2024 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"
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2024 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>;
};
11 changes: 11 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/prj.conf
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/prj_s2ram.conf
Original file line number Diff line number Diff line change
@@ -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
56 changes: 56 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(idle_flpr, LOG_LEVEL_INF);

/* Variables used to make CPU active for ~1 second */
// static struct k_timer my_timer;

Check failure on line 12 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:12 do not use C99 // comments
// static bool timer_expired;

Check failure on line 13 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:13 do not use C99 // comments
// volatile uint32_t make_busy;

Check failure on line 14 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:14 do not use C99 // comments

// void my_timer_handler(struct k_timer *dummy)

Check failure on line 16 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:16 do not use C99 // comments
// {

Check failure on line 17 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:17 do not use C99 // comments
// timer_expired = true;

Check warning on line 18 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:18 please, no space before tabs

Check failure on line 18 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:18 do not use C99 // comments
// }

Check failure on line 19 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:19 do not use C99 // comments

int main(void)
{
// int counter = 0;

Check failure on line 23 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:23 do not use C99 // comments

LOG_INF("Multicore idle_flpr test on %s", CONFIG_BOARD_TARGET);
LOG_INF("Main sleeps for %d ms", CONFIG_TEST_SLEEP_DURATION_MS);

// k_timer_init(&my_timer, my_timer_handler, NULL);

Check warning on line 28 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:28 please, no space before tabs

Check failure on line 28 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:28 do not use C99 // comments

// /* Run test forever */

Check warning on line 30 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:30 please, no space before tabs

Check failure on line 30 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

C99_COMMENTS

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:30 do not use C99 // comments
// while (1) {

Check warning on line 31 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:31 please, no space before tabs
// timer_expired = false;

Check warning on line 32 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:32 please, no space before tabs

// /* start a one-shot timer that expires after 1 second */

Check warning on line 34 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:34 please, no space before tabs
// k_timer_start(&my_timer, K_MSEC(1000), K_NO_WAIT);

Check warning on line 35 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:35 please, no space before tabs

// /* Keep CPU active for ~ 1 second */

Check warning on line 37 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:37 please, no space before tabs
// while (!timer_expired) {

Check warning on line 38 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:38 please, no space before tabs
// LOG_INF("a");

Check warning on line 39 in tests/benchmarks/multicore/idle_flpr/remote/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACE_BEFORE_TAB

tests/benchmarks/multicore/idle_flpr/remote/src/main.c:39 please, no space before tabs
// k_busy_wait(10000);
// // k_msleep(100);
// make_busy++;
// LOG_INF("b");
// k_yield();
// LOG_INF("c");
// }

// LOG_INF("Run %d", counter);
// counter++;

// /* Sleep / enter low power state */
// k_msleep(CONFIG_TEST_SLEEP_DURATION_MS);
// }

return 0;
}
94 changes: 94 additions & 0 deletions tests/benchmarks/multicore/idle_flpr/remote/src/power_off.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <zephyr/devicetree.h>
#include <hal/nrf_vpr_csr.h>

#include <zephyr/logging/log.h>
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);
}
Loading

0 comments on commit 183e19e

Please sign in to comment.