Skip to content

Commit 92e0051

Browse files
gromerogalak
authored andcommitted
tests: Add test to check uart_irq_is_pending
Add test to check if uart_irq_is_pending() correctly returns 0 (meaning there are no more RX and TX pending interrupts) when all RX and TX data is processed. Signed-off-by: Gustavo Romero <[email protected]>
1 parent bd0fe17 commit 92e0051

File tree

4 files changed

+152
-1
lines changed

4 files changed

+152
-1
lines changed

tests/drivers/uart/uart_basic_api/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ target_sources(app PRIVATE
1010
src/test_uart_poll.c
1111
)
1212
target_sources_ifdef(CONFIG_UART_INTERRUPT_DRIVEN app PRIVATE src/test_uart_fifo.c)
13+
target_sources_ifdef(CONFIG_UART_INTERRUPT_DRIVEN app PRIVATE src/test_uart_pending.c)

tests/drivers/uart/uart_basic_api/src/main.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ TC_CMD_DEFINE(test_uart_fifo_read)
2020
TC_CMD_DEFINE(test_uart_fifo_fill)
2121
TC_CMD_DEFINE(test_uart_poll_in)
2222
TC_CMD_DEFINE(test_uart_poll_out)
23+
TC_CMD_DEFINE(test_uart_pending)
2324

2425
SHELL_CMD_REGISTER(test_uart_configure, NULL, NULL,
2526
TC_CMD_ITEM(test_uart_configure));
@@ -33,6 +34,8 @@ SHELL_CMD_REGISTER(test_uart_poll_in, NULL, NULL,
3334
TC_CMD_ITEM(test_uart_poll_in));
3435
SHELL_CMD_REGISTER(test_uart_poll_out, NULL, NULL,
3536
TC_CMD_ITEM(test_uart_poll_out));
37+
SHELL_CMD_REGISTER(test_uart_pending, NULL, NULL,
38+
TC_CMD_ITEM(test_uart_pending));
3639
#endif
3740

3841
#ifndef CONFIG_UART_INTERRUPT_DRIVEN
@@ -45,6 +48,11 @@ void test_uart_fifo_read(void)
4548
{
4649
ztest_test_skip();
4750
}
51+
52+
void test_uart_pending(void)
53+
{
54+
ztest_test_skip();
55+
}
4856
#endif
4957

5058
void test_main(void)
@@ -56,7 +64,8 @@ void test_main(void)
5664
ztest_unit_test(test_uart_fifo_fill),
5765
ztest_unit_test(test_uart_fifo_read),
5866
ztest_unit_test(test_uart_poll_in),
59-
ztest_unit_test(test_uart_poll_out));
67+
ztest_unit_test(test_uart_poll_out),
68+
ztest_unit_test(test_uart_pending));
6069
ztest_run_test_suite(uart_basic_test);
6170
#endif
6271
}

tests/drivers/uart/uart_basic_api/src/test_uart.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ void test_uart_poll_out(void);
2626
void test_uart_fifo_fill(void);
2727
void test_uart_fifo_read(void);
2828
void test_uart_poll_in(void);
29+
void test_uart_pending(void);
2930

3031
#endif /* __TEST_UART_H__ */
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* Copyright (c) 2021 Linaro Limited
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* @addtogroup t_uart_basic
9+
* @{
10+
* @defgroup t_uart_fifo test_uart_pending
11+
* @brief TestPurpose: test UART uart_irq_is_pending()
12+
* @details
13+
*
14+
* Test if uart_irq_is_pending() correctly returns 0 when there are no
15+
* more RX and TX pending interrupts.
16+
*
17+
* The test consists in disabling TX IRQ so no TX interrupts are
18+
* generated and the TX IRQ pending flag is never set. At the same time
19+
* RX IRQ is enabled to let received data cause a RX IRQ and so set the
20+
* RX IRQ pending flag.
21+
*
22+
* Then a message is sent via serial to inform that the test is ready to
23+
* receive serial data, which will trigger a RX IRQ.
24+
*
25+
* Once a RX IRQ happens RX data is read by uart_fifo_read() until there
26+
* is no more RX data to be popped from FIFO and all IRQs are handled.
27+
* When that happens uart_irq_is_pending() is called and must return 0,
28+
* indicating there are no more pending interrupts to be processed. If 0
29+
* is returned the test passes.
30+
*
31+
* In some cases uart_irq_is_pending() does not correctly use the IRQ
32+
* pending flags to determine if there are pending interrupts, hence
33+
* even tho there aren't any further RX and TX IRQs to be processed it
34+
* wrongly returns 1. If 1 is returned the test fails.
35+
*
36+
* @}
37+
*/
38+
39+
#include "test_uart.h"
40+
41+
#define MAX_NUM_TRIES 512
42+
#define NOT_READY 0
43+
44+
#define FAILED 0
45+
#define PASSED 1
46+
#define WAIT 2
47+
static int volatile status;
48+
49+
static void uart_pending_callback(const struct device *dev, void *user_data)
50+
{
51+
ARG_UNUSED(user_data);
52+
53+
int num_tries = 0;
54+
char recv_char;
55+
56+
/*
57+
* If the bug is not present uart_fifo_read() will pop all
58+
* received data until there is no more RX data, thus
59+
* uart_irq_is_pending() must correctly return 0 indicating
60+
* that there are no more RX interrupts to be processed.
61+
* Otherwise uart_irq_is_pending() never returns 0 even tho
62+
* there is no more RX data in the RX buffer to be processed,
63+
* so, in that case, the test fails after MAX_NUM_TRIES attempts.
64+
*/
65+
status = PASSED;
66+
while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
67+
if (uart_irq_rx_ready(dev) == NOT_READY) {
68+
if (num_tries < MAX_NUM_TRIES) {
69+
num_tries++;
70+
continue;
71+
} else {
72+
/*
73+
* Bug: no more tries; uart_irq_is_pending()
74+
* always returned 1 in spite of having no more
75+
* RX data to be read from FIFO and no more TX
76+
* data in FIFO to be sent via serial line.
77+
* N.B. uart_irq_update() always returns 1, thus
78+
* uart_irq_is_pending() got stuck without any
79+
* real pending interrupt, i.e. no more RX and
80+
* TX data to be popped or pushed from/to FIFO.
81+
*/
82+
status = FAILED;
83+
break;
84+
}
85+
}
86+
87+
while (uart_fifo_read(dev, &recv_char, 1)) {
88+
/* Echo received char */
89+
TC_PRINT("%c", recv_char);
90+
}
91+
}
92+
}
93+
94+
static int test_pending(void)
95+
{
96+
const struct device *uart_dev = device_get_binding(UART_DEVICE_NAME);
97+
98+
/*
99+
* Set IRQ callback function to handle RX IRQ.
100+
*/
101+
uart_irq_callback_set(uart_dev, uart_pending_callback);
102+
103+
/*
104+
* Disable TX IRQ since transmitted data is not
105+
* handled by uart_pending_callback() and we don't
106+
* want to trigger any TX IRQ for this test.
107+
*/
108+
uart_irq_tx_disable(uart_dev);
109+
110+
/*
111+
* Enable RX IRQ so uart_pending_callback() can
112+
* handle input data is available in RX FIFO.
113+
*/
114+
uart_irq_rx_enable(uart_dev);
115+
116+
status = WAIT;
117+
118+
/* Inform test is ready to receive data */
119+
TC_PRINT("Please send characters to serial console\n");
120+
121+
while (status == WAIT) {
122+
/*
123+
* Wait RX handler change 'status' properly:
124+
* it will change to PASSED or FAILED after
125+
* uart_irq_is_pending() is tested by
126+
* uart_pending_callback() upon data reception.
127+
*/
128+
}
129+
130+
if (status == PASSED) {
131+
return TC_PASS;
132+
} else {
133+
return TC_FAIL;
134+
}
135+
}
136+
137+
void test_uart_pending(void)
138+
{
139+
zassert_true(test_pending() == TC_PASS, NULL);
140+
}

0 commit comments

Comments
 (0)