Skip to content

Commit b7f6aaa

Browse files
pfalconAnas Nashif
authored andcommitted
tests: uart_basic_api: Don't assume we can drink from IRQ firehose.
There're (at least) 2 UART TX interrupt causes: "tx fifo has more room" and "transmission of tx fifo complete". Zephyr API has only one function to enable TX interrupts, uart_irq_tx_enable(), so it's fair to assume it enables interrupt for both conditions. But then immediately after enabling TX IRQ, it will be fired with "tx fifo has more room" cause. If ISR doesn't do anything to fill FIFO, on some architectures, immediately after return from ISR, it will be fired again (with no instruction progress in the main application thread). That's exactly the situation with this test, and on ARM, it leads to inifnite IRQ loop. So, instead move call to uart_fifo_fill() inside ISR, and be sure to disable TX IRQ after we transmitted enough characters. Change-Id: Ibbd05acf96b01fdb128f08054819fd104d6dfae8 Signed-off-by: Paul Sokolovsky <[email protected]>
1 parent 97ee53a commit b7f6aaa

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

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

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
static volatile bool data_transmitted;
3838
static volatile bool data_received;
3939
static int char_sent;
40-
static const char *fifo_data = "This is a FIFO test.\r\n";
40+
static const char fifo_data[] = "This is a FIFO test.\r\n";
4141

42-
#define DATA_SIZE strlen(fifo_data)
42+
#define DATA_SIZE (sizeof(fifo_data) - 1)
4343

4444
static void uart_fifo_callback(struct device *dev)
4545
{
4646
u8_t recvData;
47+
static int tx_data_idx;
4748

4849
/* Verify uart_irq_update() */
4950
if (!uart_irq_update(dev)) {
@@ -52,9 +53,27 @@ static void uart_fifo_callback(struct device *dev)
5253
}
5354

5455
/* Verify uart_irq_tx_ready() */
55-
if (uart_irq_tx_ready(dev)) {
56-
data_transmitted = true;
57-
char_sent++;
56+
/* Note that TX IRQ may be disabled, but uart_irq_tx_ready() may
57+
* still return true when ISR is called for another UART interrupt,
58+
* hence additional check for i < DATA_SIZE.
59+
*/
60+
if (uart_irq_tx_ready(dev) && tx_data_idx < DATA_SIZE) {
61+
/* We arrive here by "tx ready" interrupt, so should always
62+
* be able to put at least one byte into a FIFO. If not,
63+
* well, we'll fail test.
64+
*/
65+
if (uart_fifo_fill(dev,
66+
(u8_t *)&fifo_data[tx_data_idx++], 1) > 0) {
67+
data_transmitted = true;
68+
char_sent++;
69+
}
70+
71+
if (tx_data_idx == DATA_SIZE) {
72+
/* If we transmitted everything, stop IRQ stream,
73+
* otherwise main app might never run.
74+
*/
75+
uart_irq_tx_disable(dev);
76+
}
5877
}
5978

6079
/* Verify uart_irq_rx_ready() */
@@ -104,20 +123,16 @@ static int test_fifo_fill(void)
104123
/* Verify uart_irq_tx_enable() */
105124
uart_irq_tx_enable(uart_dev);
106125

107-
/* Verify uart_fifo_fill() */
108-
for (int i = 0; i < DATA_SIZE; i++) {
109-
data_transmitted = false;
110-
while (!uart_fifo_fill(uart_dev, (u8_t *) &fifo_data[i], 1))
111-
;
112-
while (data_transmitted == false)
113-
;
114-
}
126+
k_sleep(500);
115127

116128
/* Verify uart_irq_tx_disable() */
117129
uart_irq_tx_disable(uart_dev);
118130

119-
/* strlen() doesn't include \r\n*/
120-
if (char_sent - 1 == DATA_SIZE) {
131+
if (!data_transmitted) {
132+
return TC_FAIL;
133+
}
134+
135+
if (char_sent == DATA_SIZE) {
121136
return TC_PASS;
122137
} else {
123138
return TC_FAIL;

0 commit comments

Comments
 (0)