1 #include <rtthread.h>
2 #include <rtdevice.h>
3 #include "utest.h"
4 
5 #define UART_SEND_TIMES  100
6 #define UART_TEST_NUMBER 6
7 
8 
9 #ifdef UTEST_SERIAL_TC
10 #define echo_test_buffer_size (1024)
11 
12 static rt_device_t u1serial;
13 static rt_device_t u2serial;
14 
15 static rt_uint32_t u2rx_length = 0;
16 static rt_uint32_t u2tx_length = 0;
17 
18 static rt_uint32_t u1rx_length = 0;
19 static rt_uint32_t u1tx_length = 0;
20 
21 static rt_uint8_t uart_over_flag = RT_FALSE;
22 
echo_test_u2_thread_entry(void * parameter)23 static void echo_test_u2_thread_entry(void *parameter)
24 {
25     char *uart_name = "uart2";
26 
27     u2serial = rt_device_find(uart_name);
28     if (!u2serial)
29     {
30         LOG_I("find %s failed!\n", uart_name);
31         return;
32     }
33 
34     rt_uint8_t *rx_buffer = rt_malloc(echo_test_buffer_size);
35 
36     rt_device_open(u2serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
37 
38     rt_ssize_t buf_datalen = 0;
39     while (1)
40     {
41         rt_device_control(u2serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen);
42         int32_t recbLen = rt_device_read(u2serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1);
43         if (recbLen > 0)
44         {
45             u2rx_length += recbLen;
46             u2tx_length += rt_device_write(u2serial, 0, rx_buffer, recbLen);
47 
48             if (uart_over_flag)
49                 break;
50         }
51     }
52     rt_free(rx_buffer);
53 }
54 
echo_test_u1_thread_entry(void * parameter)55 static void echo_test_u1_thread_entry(void *parameter)
56 {
57     rt_uint8_t *rx_buffer   = rt_malloc(echo_test_buffer_size);
58     rt_ssize_t  buf_datalen = 0;
59     while (1)
60     {
61         rt_device_control(u1serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen);
62         int32_t recbLen = rt_device_read(u1serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1);
63         if (recbLen > 0)
64         {
65             u1rx_length += recbLen;
66             if (uart_over_flag)
67                 break;
68         }
69     }
70 
71     rt_free(rx_buffer);
72 }
73 
74 
echo_test()75 static rt_bool_t echo_test()
76 {
77     rt_bool_t result    = RT_TRUE;
78     char     *uart_name = "uart1";
79     u1serial            = rt_device_find(uart_name);
80     if (!u1serial)
81     {
82         LOG_I("find %s failed!\n", uart_name);
83         return RT_FALSE;
84     }
85 
86     rt_uint8_t *tx_buffer = rt_malloc(echo_test_buffer_size);
87 
88     rt_device_open(u1serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
89     rt_thread_startup(rt_thread_create("serial2", echo_test_u2_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 4, 5));
90     rt_thread_startup(rt_thread_create("serial1", echo_test_u1_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 5, 5));
91 
92     uint32_t sendTotalCount = 0;
93     srand(rt_tick_get());
94     for (uint32_t count = 0; count < 1000; count++)
95     {
96         // Indefinite length of data is sent
97         uint32_t sendCount = rand() % echo_test_buffer_size;
98 
99 
100         u1tx_length    += rt_device_write(u1serial, 0, tx_buffer, sendCount);
101         sendTotalCount += sendCount;
102 
103         // Wait for the cross-send to complete
104         rt_thread_mdelay(UART_SEND_TIMES);
105 
106         if (count % 50 == 0)
107         {
108             LOG_I("echo, uart2: tx: %ld, rx: %ld", u2tx_length, u2rx_length);
109             LOG_I("echo, uart1: tx: %ld, rx: %ld", u1tx_length, u1rx_length);
110             if (u2tx_length != u2rx_length || u1tx_length != u1rx_length || u2tx_length != u1tx_length)
111             {
112                 LOG_I("echo test error!!!");
113                 result = RT_FALSE;
114                 break;
115             }
116 
117             if (u2tx_length != sendTotalCount)
118             {
119                 LOG_I("u2tx_length != sendTotalCount echo test error!!!");
120                 result = RT_FALSE;
121                 break;
122             }
123         }
124     }
125 
126     uart_over_flag = RT_TRUE;
127     // Notify the thread to exit
128     rt_device_write(u1serial, 0, tx_buffer, echo_test_buffer_size);
129     rt_thread_mdelay(30);
130 
131     {
132         rt_device_t uart_dev = rt_device_find("uart2");
133         while (rt_device_close(uart_dev) != -RT_ERROR);
134     }
135     {
136         rt_device_t uart_dev = rt_device_find("uart1");
137         while (rt_device_close(uart_dev) != -RT_ERROR);
138     }
139     rt_free(tx_buffer);
140     return result;
141 }
142 
uart_test_nonblocking_tx(void)143 static void uart_test_nonblocking_tx(void)
144 {
145     uassert_true(echo_test());
146 }
147 
utest_tc_init(void)148 static rt_err_t utest_tc_init(void)
149 {
150     return RT_EOK;
151 }
152 
utest_tc_cleanup(void)153 static rt_err_t utest_tc_cleanup(void)
154 {
155     u1serial       = RT_NULL;
156     u2serial       = RT_NULL;
157     u2rx_length    = 0;
158     u2tx_length    = 0;
159     u1rx_length    = 0;
160     u1tx_length    = 0;
161     uart_over_flag = RT_FALSE;
162     return RT_EOK;
163 }
164 
testcase(void)165 static void testcase(void)
166 {
167     UTEST_UNIT_RUN(uart_test_nonblocking_tx);
168 }
169 UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_qemu_echo", utest_tc_init, utest_tc_cleanup, 10);
170 
171 #endif
172