Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: modem: backends: uart: Add UART backend test suite
The UART backend test suite performs 9 iterations of: 1. Open UART backend pipe 2. Transmit 8192 bytes of pseudo random data 3. Receive and validate bytes 4. close UART backend pipe The test is run on real hardware, with the TX/RX pins connected to each other to provide loopback functionality. The test suite has been run on a STM32 and an nRF5340 board. The test suite tests both the UART interrupt driven and async APIs. Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
- Loading branch information
1 parent
0df16b9
commit 8c3b4de
Showing
6 changed files
with
325 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Copyright (c) 2023 Trackunit Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(modem_backend_uart_test) | ||
|
||
target_sources(app PRIVATE src/main.c) |
36 changes: 36 additions & 0 deletions
36
tests/subsys/modem/backends/uart/boards/b_u585i_iot02a.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Pins 2 and 3 must be connected to each other on the STMOD+1 connector to | ||
* loopback RX/TX. | ||
*/ | ||
|
||
/ { | ||
aliases { | ||
test-uart = &usart2; | ||
}; | ||
}; | ||
|
||
&gpioh { | ||
misc_fixed_usart2 { | ||
gpio-hog; | ||
gpios = <13 GPIO_ACTIVE_HIGH>; | ||
output-high; | ||
}; | ||
}; | ||
|
||
&gpdma1 { | ||
status = "okay"; | ||
}; | ||
|
||
/* BG95 */ | ||
&usart2 { | ||
pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3 &usart2_rts_pa1 &usart2_cts_pa0>; | ||
pinctrl-names = "default"; | ||
current-speed = <115200>; | ||
/* hw-flow-control; */ | ||
|
||
dmas = <&gpdma1 0 27 STM32_DMA_PERIPH_TX | ||
&gpdma1 1 26 STM32_DMA_PERIPH_RX>; | ||
dma-names = "tx", "rx"; | ||
|
||
status = "okay"; | ||
}; |
38 changes: 38 additions & 0 deletions
38
tests/subsys/modem/backends/uart/boards/nrf5340dk_nrf5340_cpuapp.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Pins P1.10 and P1.11 must be connected to each other to loopback RX/TX. | ||
*/ | ||
|
||
/ { | ||
aliases { | ||
test-uart = &uart1; | ||
}; | ||
}; | ||
|
||
&uart1 { | ||
status = "okay"; | ||
current-speed = <115200>; | ||
pinctrl-0 = <&uart1_default>; | ||
pinctrl-1 = <&uart1_sleep>; | ||
hw-flow-control; | ||
pinctrl-names = "default", "sleep"; | ||
}; | ||
|
||
&pinctrl { | ||
uart1_default: uart1_default { | ||
group1 { | ||
psels = <NRF_PSEL(UART_TX, 1, 11)>; | ||
}; | ||
group2 { | ||
psels = <NRF_PSEL(UART_RX, 1, 10)>; | ||
bias-pull-up; | ||
}; | ||
}; | ||
|
||
uart1_sleep: uart1_sleep { | ||
group1 { | ||
psels = <NRF_PSEL(UART_TX, 1, 10)>, | ||
<NRF_PSEL(UART_RX, 1, 11)>; | ||
low-power-enable; | ||
}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Copyright (c) 2023 Trackunit Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
CONFIG_MODEM_MODULES=y | ||
CONFIG_MODEM_BACKEND_UART=y | ||
CONFIG_SERIAL=y | ||
CONFIG_ZTEST=y | ||
CONFIG_LOG=y | ||
CONFIG_ZTEST_SHUFFLE=y | ||
CONFIG_ZTEST_SHUFFLE_TEST_REPEAT_COUNT=3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/* | ||
* Copyright (c) 2023 Trackunit Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/* | ||
* This test suite sets up a modem_backend_uart instance connected to a UART which has its | ||
* RX and TX pins wired together to provide loopback functionality. A large number of bytes | ||
* containing a sequence of pseudo random numbers are then transmitted, received, and validated. | ||
* | ||
* The test suite repeats three times, opening and clsoing the modem_pipe attached to the | ||
* modem_backend_uart instance before and after the tests respectively. | ||
*/ | ||
|
||
/*************************************************************************************************/ | ||
/* Dependencies */ | ||
/*************************************************************************************************/ | ||
#include <zephyr/ztest.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/sys/atomic.h> | ||
#include <zephyr/modem/backend/uart.h> | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
/*************************************************************************************************/ | ||
/* Mock pipe */ | ||
/*************************************************************************************************/ | ||
static const struct device *uart = DEVICE_DT_GET(DT_ALIAS(test_uart)); | ||
static struct modem_backend_uart uart_backend; | ||
static struct modem_pipe *pipe; | ||
K_SEM_DEFINE(receive_ready_sem, 0, 1); | ||
|
||
/*************************************************************************************************/ | ||
/* Buffers */ | ||
/*************************************************************************************************/ | ||
static uint8_t backend_receive_buffer[4096]; | ||
static uint8_t backend_transmit_buffer[4096]; | ||
RING_BUF_DECLARE(transmit_ring_buf, 4096); | ||
static uint8_t receive_buffer[4096]; | ||
|
||
/*************************************************************************************************/ | ||
/* Modem pipe callback */ | ||
/*************************************************************************************************/ | ||
static void modem_pipe_callback_handler(struct modem_pipe *pipe, enum modem_pipe_event event, | ||
void *user_data) | ||
{ | ||
switch (event) { | ||
case MODEM_PIPE_EVENT_RECEIVE_READY: | ||
k_sem_give(&receive_ready_sem); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
/*************************************************************************************************/ | ||
/* Helpers */ | ||
/*************************************************************************************************/ | ||
static uint32_t transmit_prng_state = 1234; | ||
static uint32_t receive_prng_state = 1234; | ||
static uint32_t transmit_size_prng_state; | ||
|
||
static uint8_t transmit_prng_random(void) | ||
{ | ||
transmit_prng_state = ((1103515245 * transmit_prng_state) + 12345) % (1U << 31); | ||
return (uint8_t)(transmit_prng_state & 0xFF); | ||
} | ||
|
||
static uint8_t receive_prng_random(void) | ||
{ | ||
receive_prng_state = ((1103515245 * receive_prng_state) + 12345) % (1U << 31); | ||
return (uint8_t)(receive_prng_state & 0xFF); | ||
} | ||
|
||
static void prng_reset(void) | ||
{ | ||
transmit_prng_state = 1234; | ||
receive_prng_state = 1234; | ||
transmit_size_prng_state = 0; | ||
} | ||
|
||
static void fill_transmit_ring_buf(void) | ||
{ | ||
uint32_t space = ring_buf_space_get(&transmit_ring_buf); | ||
uint8_t data; | ||
|
||
for (uint32_t i = 0; i < space; i++) { | ||
data = transmit_prng_random(); | ||
ring_buf_put(&transmit_ring_buf, &data, 1); | ||
} | ||
} | ||
|
||
static uint32_t transmit_size_prng_random(void) | ||
{ | ||
uint32_t size = 1; | ||
|
||
for (uint8_t i = 0; i < transmit_size_prng_state; i++) { | ||
size = size * 2; | ||
} | ||
|
||
transmit_size_prng_state = transmit_size_prng_state == 11 | ||
? 0 | ||
: transmit_size_prng_state + 1; | ||
|
||
return size; | ||
} | ||
|
||
static int transmit_prng(uint32_t remaining) | ||
{ | ||
uint8_t *reserved; | ||
uint32_t reserved_size; | ||
uint32_t transmit_size; | ||
int ret; | ||
|
||
fill_transmit_ring_buf(); | ||
reserved_size = ring_buf_get_claim(&transmit_ring_buf, &reserved, UINT32_MAX); | ||
transmit_size = MIN(transmit_size_prng_random(), reserved_size); | ||
transmit_size = MIN(remaining, transmit_size); | ||
ret = modem_pipe_transmit(pipe, reserved, transmit_size); | ||
if (ret < 0) { | ||
return ret; | ||
} | ||
printk("TX: %u,%u\n", transmit_size, (uint32_t)ret); | ||
__ASSERT(ret <= remaining, "Impossible number of bytes sent %u", (uint32_t)ret); | ||
ring_buf_get_finish(&transmit_ring_buf, ret); | ||
return ret; | ||
} | ||
|
||
static int receive_prng(void) | ||
{ | ||
int ret = 0; | ||
|
||
if (k_sem_take(&receive_ready_sem, K_NO_WAIT) == 0) { | ||
ret = modem_pipe_receive(pipe, receive_buffer, sizeof(receive_buffer)); | ||
if (ret < 0) { | ||
return -EFAULT; | ||
} | ||
for (uint32_t i = 0; i < (uint32_t)ret; i++) { | ||
if (receive_prng_random() != receive_buffer[i]) { | ||
return -EFAULT; | ||
} | ||
} | ||
printk("RX: %u\n", (uint32_t)ret); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
/*************************************************************************************************/ | ||
/* Test setup */ | ||
/*************************************************************************************************/ | ||
static void *test_modem_backend_uart_setup(void) | ||
{ | ||
const struct modem_backend_uart_config config = { | ||
.uart = uart, | ||
.receive_buf = backend_receive_buffer, | ||
.receive_buf_size = 1024, | ||
.transmit_buf = backend_transmit_buffer, | ||
.transmit_buf_size = 1024, | ||
}; | ||
|
||
pipe = modem_backend_uart_init(&uart_backend, &config); | ||
modem_pipe_attach(pipe, modem_pipe_callback_handler, NULL); | ||
k_msleep(10); | ||
|
||
return NULL; | ||
} | ||
|
||
static void test_modem_backend_uart_before(void *f) | ||
{ | ||
prng_reset(); | ||
ring_buf_reset(&transmit_ring_buf); | ||
k_sem_reset(&receive_ready_sem); | ||
__ASSERT_NO_MSG(modem_pipe_open(pipe) == 0); | ||
} | ||
|
||
static void test_modem_backend_uart_after(void *f) | ||
{ | ||
__ASSERT_NO_MSG(modem_pipe_close(pipe) == 0); | ||
} | ||
|
||
/*************************************************************************************************/ | ||
/* Tests */ | ||
/*************************************************************************************************/ | ||
ZTEST(modem_backend_uart_suite, test_transmit_receive) | ||
{ | ||
int32_t remaining = 8192; | ||
uint32_t received = 0; | ||
uint32_t transmitted = 0; | ||
int ret; | ||
|
||
while ((remaining != 0) || (received < 8192)) { | ||
ret = transmit_prng(remaining); | ||
zassert(ret > -1, "Failed to transmit data"); | ||
remaining -= (uint32_t)ret; | ||
transmitted += (uint32_t)ret; | ||
printk("TX ACC: %u\n", transmitted); | ||
|
||
while (received < transmitted) { | ||
ret = receive_prng(); | ||
zassert(ret > -1, "Recevied data is corrupted"); | ||
received += (uint32_t)ret; | ||
k_yield(); | ||
} | ||
} | ||
} | ||
|
||
ZTEST_SUITE(modem_backend_uart_suite, NULL, test_modem_backend_uart_setup, | ||
test_modem_backend_uart_before, test_modem_backend_uart_after, NULL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright (c) 2023 Trackunit Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
tests: | ||
modem.backends.uart.async: | ||
tags: modem_backend | ||
harness: ztest | ||
platform_allow: | ||
- b_u585i_iot02a | ||
- nrf5340dk_nrf5340_cpuapp | ||
extra_configs: | ||
- CONFIG_UART_ASYNC_API=y | ||
|
||
modem.backends.uart.isr: | ||
tags: modem_backend | ||
harness: ztest | ||
platform_allow: | ||
- b_u585i_iot02a | ||
- nrf5340dk_nrf5340_cpuapp | ||
extra_configs: | ||
- CONFIG_UART_INTERRUPT_DRIVEN=y |