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
2224static const struct device * ipc0_instance = DEVICE_DT_GET (DT_NODELABEL (ipc0 ));
2325static volatile bool ipc0_bounded ;
2426K_SEM_DEFINE (bound_sem , 0 , 1 );
2527K_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+
2739static struct k_timer timer_reboot ;
2840static 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