Skip to content

Commit c459028

Browse files
committed
tests: ipc: ipc_sessions: Add long transfers test
Add tests for transfers that would overflow the buffer. Signed-off-by: Radosław Koppel <[email protected]>
1 parent f2a8725 commit c459028

File tree

6 files changed

+337
-5
lines changed

6 files changed

+337
-5
lines changed

tests/subsys/ipc/ipc_sessions/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,11 @@ config IPC_TEST_SKIP_CORE_RESET
2020
help
2121
Some of the cores cannot be safely restarted.
2222
Skip the tests that require it in such a cases.
23+
24+
config IPC_TEST_BLOCK_SIZE
25+
int "Block size for multiple transfers test"
26+
default 32
27+
28+
config IPC_TEST_BLOCK_CNT
29+
int "Number of blocks for multiple transfers test"
30+
default 8000

tests/subsys/ipc/ipc_sessions/common/test_commands.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ enum ipc_test_commands {
1717
IPC_TEST_CMD_ECHO_RSP, /**< Echo respond */
1818
IPC_TEST_CMD_REBOND, /**< Unbond and rebond back whole interface */
1919
IPC_TEST_CMD_REBOOT, /**< Restart remote CPU after a given delay */
20+
/* Commands used for data transfer test */
21+
IPC_TEST_CMD_RXSTART, /**< Start receiving data */
22+
IPC_TEST_CMD_TXSTART, /**< Start sending data */
23+
IPC_TEST_CMD_RXGET, /**< Get rx status */
24+
IPC_TEST_CMD_TXGET, /**< Get tx status */
25+
IPC_TEST_CMD_XSTAT, /**< rx/tx status response */
26+
IPC_TEST_CMD_XDATA, /**< Transfer data block */
27+
/* End of commands used for data transfer test */
2028
};
2129

2230
/**
@@ -43,4 +51,31 @@ struct ipc_test_cmd_reboot {
4351
uint32_t timeout_ms;
4452
};
4553

54+
/**
55+
* @brief Start the rx or tx transfer
56+
*/
57+
struct ipc_test_cmd_xstart {
58+
struct ipc_test_cmd base;
59+
uint32_t blk_size;
60+
uint32_t blk_cnt;
61+
uint32_t seed;
62+
};
63+
64+
/**
65+
* @brief Get the status of rx or tx transfer
66+
*/
67+
struct ipc_test_cmd_xstat {
68+
struct ipc_test_cmd base;
69+
uint32_t blk_cnt; /**< Transfers left */
70+
int32_t result; /**< Current result */
71+
};
72+
73+
/**
74+
* @brief The result of rx or tx transfer
75+
*/
76+
struct ipc_test_cmd_xrsp {
77+
struct ipc_test_cmd base;
78+
int32_t result;
79+
};
80+
4681
#endif /* TEST_COMMANDS_H */

tests/subsys/ipc/ipc_sessions/prj.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Copyright 2021 Carlo Caione <[email protected]>
22
# SPDX-License-Identifier: Apache-2.0
33

4+
# We need rand_r function
5+
CONFIG_GNU_C_EXTENSIONS=y
6+
47
CONFIG_ZTEST=y
58
CONFIG_MMU=y
69
CONFIG_IPC_SERVICE=y

tests/subsys/ipc/ipc_sessions/remote/prj.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright (c) 2024 Nordic Semiconductor ASA
22
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
33

4+
# We need rand_r function
5+
CONFIG_GNU_C_EXTENSIONS=y
46
CONFIG_PRINTK=y
57
CONFIG_EVENTS=y
68

tests/subsys/ipc/ipc_sessions/remote/src/remote.c

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <stdlib.h>
78
#include <zephyr/kernel.h>
89
#include <zephyr/device.h>
910
#include <zephyr/devicetree.h>
@@ -18,12 +19,23 @@ LOG_MODULE_REGISTER(remote, LOG_LEVEL_INF);
1819

1920
#define IPC_TEST_EV_REBOND 0x01
2021
#define IPC_TEST_EV_BOND 0x02
22+
#define IPC_TEST_EV_TXTEST 0x04
2123

2224
static const struct device *ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
2325
static volatile bool ipc0_bounded;
2426
K_SEM_DEFINE(bound_sem, 0, 1);
2527
K_EVENT_DEFINE(ipc_ev_req);
2628

29+
struct ipc_xfer_params {
30+
uint32_t blk_size;
31+
uint32_t blk_cnt;
32+
unsigned int seed;
33+
int result;
34+
};
35+
36+
static struct ipc_xfer_params ipc_rx_params;
37+
static struct ipc_xfer_params ipc_tx_params;
38+
2739
static struct k_timer timer_reboot;
2840
static struct k_timer timer_rebond;
2941

@@ -136,8 +148,6 @@ static void ep_recv(const void *data, size_t len, void *priv)
136148
return;
137149
}
138150

139-
LOG_INF("Command received: %u", cmd->cmd);
140-
141151
switch (cmd->cmd) {
142152
case IPC_TEST_CMD_NONE:
143153
LOG_INF("Command processing: NONE");
@@ -189,6 +199,99 @@ static void ep_recv(const void *data, size_t len, void *priv)
189199
k_timer_start(&timer_reboot, K_MSEC(cmd_reboot->timeout_ms), K_FOREVER);
190200
break;
191201
}
202+
case IPC_TEST_CMD_RXSTART: {
203+
LOG_INF("Command processing: RXSTART");
204+
205+
struct ipc_test_cmd_xstart *cmd_rxstart = (struct ipc_test_cmd_xstart *)cmd;
206+
207+
ipc_rx_params.blk_size = cmd_rxstart->blk_size;
208+
ipc_rx_params.blk_cnt = cmd_rxstart->blk_cnt;
209+
ipc_rx_params.seed = cmd_rxstart->seed;
210+
ipc_rx_params.result = 0;
211+
break;
212+
}
213+
case IPC_TEST_CMD_TXSTART: {
214+
LOG_INF("Command processing: TXSTART");
215+
216+
struct ipc_test_cmd_xstart *cmd_txstart = (struct ipc_test_cmd_xstart *)cmd;
217+
218+
ipc_tx_params.blk_size = cmd_txstart->blk_size;
219+
ipc_tx_params.blk_cnt = cmd_txstart->blk_cnt;
220+
ipc_tx_params.seed = cmd_txstart->seed;
221+
ipc_tx_params.result = 0;
222+
k_event_set(&ipc_ev_req, IPC_TEST_EV_TXTEST);
223+
break;
224+
}
225+
case IPC_TEST_CMD_RXGET: {
226+
LOG_INF("Command processing: RXGET");
227+
228+
int ret;
229+
struct ipc_test_cmd_xstat cmd_stat = {
230+
.base.cmd = IPC_TEST_CMD_XSTAT,
231+
.blk_cnt = ipc_rx_params.blk_cnt,
232+
.result = ipc_rx_params.result
233+
};
234+
235+
ret = ipc_service_send(ep, &cmd_stat, sizeof(cmd_stat));
236+
if (ret < 0) {
237+
LOG_ERR("RXGET response send failed");
238+
}
239+
break;
240+
}
241+
case IPC_TEST_CMD_TXGET: {
242+
LOG_INF("Command processing: TXGET");
243+
244+
int ret;
245+
struct ipc_test_cmd_xstat cmd_stat = {
246+
.base.cmd = IPC_TEST_CMD_XSTAT,
247+
.blk_cnt = ipc_tx_params.blk_cnt,
248+
.result = ipc_tx_params.result
249+
};
250+
251+
ret = ipc_service_send(ep, &cmd_stat, sizeof(cmd_stat));
252+
if (ret < 0) {
253+
LOG_ERR("TXGET response send failed");
254+
}
255+
break;
256+
}
257+
case IPC_TEST_CMD_XDATA: {
258+
if ((ipc_rx_params.blk_cnt % 1000) == 0) {
259+
/* Logging only every N-th command not to slowdown the transfer too much */
260+
LOG_INF("Command processing: XDATA (left: %u)", ipc_rx_params.blk_cnt);
261+
}
262+
263+
/* Ignore if there is an error */
264+
if (ipc_rx_params.result) {
265+
LOG_ERR("There is error in Rx transfer already");
266+
break;
267+
}
268+
269+
if (len != ipc_rx_params.blk_size + offsetof(struct ipc_test_cmd, data)) {
270+
LOG_ERR("Size mismatch");
271+
ipc_rx_params.result = -EMSGSIZE;
272+
break;
273+
}
274+
275+
if (ipc_rx_params.blk_cnt <= 0) {
276+
LOG_ERR("Data not expected");
277+
ipc_rx_params.result = -EFAULT;
278+
break;
279+
}
280+
281+
/* Check the data */
282+
for (size_t n = 0; n < ipc_rx_params.blk_size; ++n) {
283+
uint8_t expected = (uint8_t)rand_r(&ipc_rx_params.seed);
284+
285+
if (cmd->data[n] != expected) {
286+
LOG_ERR("Data value error at %u", n);
287+
ipc_rx_params.result = -EINVAL;
288+
break;
289+
}
290+
}
291+
292+
ipc_rx_params.blk_cnt -= 1;
293+
break;
294+
}
192295
default:
193296
LOG_ERR("Unhandled command: %u", cmd->cmd);
194297
break;
@@ -299,6 +402,45 @@ int main(void)
299402
}
300403
LOG_INF("Bonding done");
301404
}
405+
if (ev & IPC_TEST_EV_TXTEST) {
406+
LOG_INF("Transfer TX test started");
407+
408+
size_t cmd_size = ipc_tx_params.blk_size + offsetof(struct ipc_test_cmd, data);
409+
struct ipc_test_cmd *cmd_data = k_malloc(cmd_size);
410+
411+
if (!cmd_data) {
412+
LOG_ERR("Cannot create TX test buffer");
413+
ipc_tx_params.result = -ENOMEM;
414+
continue;
415+
}
416+
417+
LOG_INF("Initial seed: %u", ipc_tx_params.seed);
418+
419+
cmd_data->cmd = IPC_TEST_CMD_XDATA;
420+
for (/* No init */; ipc_tx_params.blk_cnt > 0; --ipc_tx_params.blk_cnt) {
421+
int ret;
422+
423+
if (ipc_tx_params.blk_cnt % 1000 == 0) {
424+
LOG_INF("Sending: %u blocks left", ipc_tx_params.blk_cnt);
425+
}
426+
/* Generate the block data */
427+
for (size_t n = 0; n < ipc_tx_params.blk_size; ++n) {
428+
cmd_data->data[n] = (uint8_t)rand_r(&ipc_tx_params.seed);
429+
}
430+
do {
431+
ret = ipc_service_send(ep_cfg.priv, cmd_data, cmd_size);
432+
} while (ret == -ENOMEM);
433+
if (ret < 0) {
434+
LOG_ERR("Cannot send TX test buffer: %d", ret);
435+
ipc_tx_params.result = -EIO;
436+
continue;
437+
}
438+
}
439+
440+
k_free(cmd_data);
441+
442+
LOG_INF("Transfer TX test finished");
443+
}
302444

303445

304446
}

0 commit comments

Comments
 (0)