Skip to content

Commit

Permalink
[nrf fromtree] tests: susbys: Implement performance test for the NRFS
Browse files Browse the repository at this point in the history
Add NRFS service handling performance test.

Signed-off-by: Bartosz Miller <[email protected]>
(cherry picked from commit 9d20c5c382d9e92529b7232c84f6bd7355cb39d0)
  • Loading branch information
nordic-bami authored and rlubos committed Feb 10, 2025
1 parent 693769a commit 1ca0ac9
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 0 deletions.
19 changes: 19 additions & 0 deletions tests/subsys/nrfs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#

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(nrfs)

target_sources(app PRIVATE src/main.c)
9 changes: 9 additions & 0 deletions tests/subsys/nrfs/Kconfig.sysbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

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

config REMOTE_BOARD
string
default "$(BOARD)/nrf54h20/cpurad" if SOC_NRF54H20_CPUAPP
default "$(BOARD)/nrf54h20/cpuapp" if SOC_NRF54H20_CPURAD
7 changes: 7 additions & 0 deletions tests/subsys/nrfs/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The purpose of this test suite is to validate
NRFS services request handling performance.

These reaquest are propagated over IPC.

MRAM latency serivice and Temperature service
are used as benchmarks.
21 changes: 21 additions & 0 deletions tests/subsys/nrfs/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CONFIG_ZTEST=y
CONFIG_TEST_USERSPACE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_ISR_STACK_SIZE=1024
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

CONFIG_NRFS=y
CONFIG_NRFS_MRAM_SERVICE_ENABLED=y
CONFIG_NRFS_TEMP_SERVICE_ENABLED=y
CONFIG_CLOCK_CONTROL=n

CONFIG_ASSERT=y

CONFIG_SERIAL=y
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=n
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
12 changes: 12 additions & 0 deletions tests/subsys/nrfs/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(remote)

target_sources(app PRIVATE ../src/main.c)
21 changes: 21 additions & 0 deletions tests/subsys/nrfs/remote/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CONFIG_ZTEST=y
CONFIG_TEST_USERSPACE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_ISR_STACK_SIZE=1024
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

CONFIG_NRFS=y
CONFIG_NRFS_MRAM_SERVICE_ENABLED=y
CONFIG_NRFS_TEMP_SERVICE_ENABLED=y
CONFIG_CLOCK_CONTROL=n

CONFIG_ASSERT=y

CONFIG_SERIAL=y
CONFIG_PRINTK=y
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=n
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
141 changes: 141 additions & 0 deletions tests/subsys/nrfs/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/device.h>
#include <internal/nrfs_backend.h>
#include <nrfs_backend_ipc_service.h>
#include <nrfs_mram.h>
#include <nrfs_temp.h>
#include <zephyr/ztest.h>

#define IPC_BACKEND_CONNECTION_TIMEOUT_MS 5000
#define NUM_OF_MRAM_REQUESTS 10000
#define MRAM_REQUESTS_DEAD_TIME_MS 1
#define NUM_OF_TEMP_REQUESTS 100
#define TEMP_REQUESTS_DEAD_TIME_MS 100

struct ipc_perf_result {
uint32_t sent_requests;
uint32_t handled_requests;
uint32_t failed_to_send;
};

static volatile uint32_t tst_perf_served_mram_requests;
static volatile uint32_t tst_perf_served_temp_meas_requests;

/*
* Callback function for counting handled TEMP service requests
*/
static void temp_handler_for_performance_test(nrfs_temp_evt_t const *p_evt, void *context)
{
switch (p_evt->type) {
case NRFS_TEMP_EVT_MEASURE_DONE:
tst_perf_served_temp_meas_requests++;
default:
break;
}
}

/*
* Callback function for counting handled MRAM service requests
*/
static void mram_latency_handler_for_performance_test(nrfs_mram_latency_evt_t const *p_evt,
void *context)
{
switch (p_evt->type) {
case NRFS_MRAM_LATENCY_REQ_APPLIED:
tst_perf_served_mram_requests++;
default:
break;
}
}

/*
* Test NRFS MRAM latency service requests handling performance
*/
ZTEST(nrfs_stress_test, test_mram_nrfs_requests_performance)
{
struct ipc_perf_result tst_ipc_perf_result;
uint32_t request_counter = 0;
volatile int32_t tst_ctx = 1;

TC_PRINT("START test_mram_nrfs_requests_performance\n");
zassert_equal(nrfs_mram_init(mram_latency_handler_for_performance_test), NRFS_SUCCESS,
"Failed to initialise NRFS MRAM latency service");
memset(&tst_ipc_perf_result, 0, sizeof(tst_ipc_perf_result));
while (request_counter < NUM_OF_MRAM_REQUESTS) {
if (nrfs_mram_set_latency(true, (void *)tst_ctx) == NRFS_SUCCESS) {
tst_ipc_perf_result.sent_requests++;
} else {
tst_ipc_perf_result.failed_to_send++;
}
k_msleep(MRAM_REQUESTS_DEAD_TIME_MS);
tst_ctx++;
request_counter++;
}
/* wait for any remaining requests responses */
k_msleep(10 * MRAM_REQUESTS_DEAD_TIME_MS);
tst_ipc_perf_result.handled_requests = tst_perf_served_mram_requests;
TC_PRINT("STOP test_mram_nrfs_requests_performance\n");
TC_PRINT("SENT: %d, HANDLED: %d, FAILED TO SEND: %d\n", tst_ipc_perf_result.sent_requests,
tst_ipc_perf_result.handled_requests, tst_ipc_perf_result.failed_to_send);
zassert_equal(tst_ipc_perf_result.sent_requests, tst_ipc_perf_result.handled_requests,
"NRFS MRAM requests sent != served");
}

/*
* Test temperature service requests handling performance
*/
ZTEST(nrfs_stress_test, test_temperature_nrfs_requests_performance)
{
struct ipc_perf_result tst_ipc_perf_result;
uint32_t request_counter = 0;
volatile int32_t tst_ctx = 1;

TC_PRINT("START test_temperature_nrfs_requests_performance\n");
zassert_equal(nrfs_temp_init(temp_handler_for_performance_test), NRFS_SUCCESS,
"Failed to initialise NRFS temperature service");
memset((void *)&tst_ipc_perf_result, 0, sizeof(tst_ipc_perf_result));
while (request_counter < NUM_OF_TEMP_REQUESTS) {
if (nrfs_temp_measure_request((void *)tst_ctx) == NRFS_SUCCESS) {
tst_ipc_perf_result.sent_requests++;
} else {
tst_ipc_perf_result.failed_to_send++;
}
k_msleep(TEMP_REQUESTS_DEAD_TIME_MS);
tst_ctx++;
request_counter++;
}
/* wait for any remaining requests responses */
k_msleep(10 * TEMP_REQUESTS_DEAD_TIME_MS);
tst_ipc_perf_result.handled_requests = tst_perf_served_temp_meas_requests;
TC_PRINT("STOP test_temperature_nrfs_requests_performance\n");
TC_PRINT("SENT: %d, HANDLED: %d, FAILED TO SEND: %d\n", tst_ipc_perf_result.sent_requests,
tst_ipc_perf_result.handled_requests, tst_ipc_perf_result.failed_to_send);
zassert_equal(tst_ipc_perf_result.sent_requests, tst_ipc_perf_result.handled_requests,
"NRFS TEMP requests sent != served");
}

/*
* Test setup
*/
static void *test_setup(void)
{
int ret;

tst_perf_served_mram_requests = 0;
tst_perf_served_temp_meas_requests = 0;

TC_PRINT("Hello World! %s\n", CONFIG_BOARD_TARGET);
TC_PRINT("Waiting for NRFS backend init\n");

/* Wait for IPC backend connection */
ret = nrfs_backend_wait_for_connection(K_MSEC(IPC_BACKEND_CONNECTION_TIMEOUT_MS));
zassert_equal(ret, 0, "Failed to establih NRFS backend connection. err: %d", ret);
return NULL;
}

ZTEST_SUITE(nrfs_stress_test, NULL, test_setup, NULL, NULL, NULL);
18 changes: 18 additions & 0 deletions tests/subsys/nrfs/sysbuild.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "")
message(FATAL_ERROR "REMOTE_BOARD must be set to a valid board name")
endif()

# Add remote project
ExternalZephyrProject_Add(
APPLICATION remote
SOURCE_DIR ${APP_DIR}/remote
BOARD ${SB_CONFIG_REMOTE_BOARD}
BOARD_REVISION ${BOARD_REVISION}
)

# Add a dependency so that the remote image will be built and flashed first
add_dependencies(nrfs remote)
sysbuild_add_dependencies(FLASH nrfs remote)
14 changes: 14 additions & 0 deletions tests/subsys/nrfs/testcase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
common:
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
- nrf54h20dk/nrf54h20/cpurad
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
- nrf54h20dk/nrf54h20/cpurad
tags:
- nrfs
harness: ztest
sysbuild: true

tests:
subsys.nrfs.stress_test: {}

0 comments on commit 1ca0ac9

Please sign in to comment.