uart_rxnb_txnb.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-06-16 KyleChan the first version
  9. */
  10. #include <rtthread.h>
  11. #include "utest.h"
  12. #include <rtdevice.h>
  13. #include <stdlib.h>
  14. #ifdef UTEST_SERIAL_TC
  15. static struct rt_serial_device *serial;
  16. static rt_sem_t tx_sem;
  17. static rt_sem_t rx_sem;
  18. static rt_uint8_t uart_over_flag;
  19. static rt_bool_t uart_result = RT_TRUE;
  20. static rt_err_t uart_find(void)
  21. {
  22. serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  23. if (serial == RT_NULL)
  24. {
  25. LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
  26. return -RT_ERROR;
  27. }
  28. return RT_EOK;
  29. }
  30. static rt_err_t uart_tx_completion(rt_device_t device, void *buffer)
  31. {
  32. rt_sem_release(tx_sem);
  33. return RT_EOK;
  34. }
  35. static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size)
  36. {
  37. rt_sem_release(rx_sem);
  38. return RT_EOK;
  39. }
  40. static void uart_send_entry(void *parameter)
  41. {
  42. rt_uint8_t *uart_write_buffer;
  43. rt_uint16_t send_len, len = 0;
  44. rt_err_t result;
  45. rt_uint32_t i = 0;
  46. send_len = *(rt_uint16_t *)parameter;
  47. /* assign send buffer */
  48. uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
  49. if (uart_write_buffer == RT_NULL)
  50. {
  51. LOG_E("Without spare memory for uart dma!");
  52. uart_result = RT_FALSE;
  53. return;
  54. }
  55. rt_memset(uart_write_buffer, 0, send_len);
  56. for (i = 0; i < send_len; i++)
  57. {
  58. uart_write_buffer[i] = (rt_uint8_t)i;
  59. }
  60. /* send buffer */
  61. while (send_len - len)
  62. {
  63. len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
  64. result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
  65. if (result != RT_EOK)
  66. {
  67. LOG_E("take sem err in send.");
  68. }
  69. }
  70. rt_free(uart_write_buffer);
  71. }
  72. static void uart_rec_entry(void *parameter)
  73. {
  74. rt_uint16_t rev_len;
  75. rev_len = *(rt_uint16_t *)parameter;
  76. rt_uint8_t *uart_write_buffer;
  77. uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
  78. rt_int32_t cnt, i;
  79. rt_uint8_t last_old_data;
  80. rt_bool_t fisrt_flag = RT_TRUE;
  81. rt_uint32_t all_receive_length = 0;
  82. while (1)
  83. {
  84. rt_err_t result;
  85. result = rt_sem_take(rx_sem, RT_WAITING_FOREVER);
  86. if (result != RT_EOK)
  87. {
  88. LOG_E("take sem err in recv.");
  89. }
  90. cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len);
  91. if (cnt == 0)
  92. {
  93. continue;
  94. }
  95. if (fisrt_flag != RT_TRUE)
  96. {
  97. if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
  98. {
  99. LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
  100. uart_result = RT_FALSE;
  101. rt_free(uart_write_buffer);
  102. return;
  103. }
  104. }
  105. else
  106. {
  107. fisrt_flag = RT_FALSE;
  108. }
  109. for (i = 0; i < cnt - 1; i++)
  110. {
  111. if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
  112. {
  113. LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
  114. uart_result = RT_FALSE;
  115. rt_free(uart_write_buffer);
  116. return;
  117. }
  118. }
  119. all_receive_length += cnt;
  120. if (all_receive_length >= rev_len)
  121. break;
  122. else
  123. last_old_data = uart_write_buffer[cnt - 1];
  124. }
  125. rt_free(uart_write_buffer);
  126. uart_over_flag = RT_TRUE;
  127. }
  128. static rt_err_t uart_api(rt_uint16_t test_buf)
  129. {
  130. rt_thread_t thread_send = RT_NULL;
  131. rt_thread_t thread_recv = RT_NULL;
  132. rt_err_t result = RT_EOK;
  133. uart_over_flag = RT_FALSE;
  134. result = uart_find();
  135. if (result != RT_EOK)
  136. {
  137. return -RT_ERROR;
  138. }
  139. rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO);
  140. if (rx_sem == RT_NULL)
  141. {
  142. LOG_E("Init rx_sem failed.");
  143. uart_result = RT_FALSE;
  144. return -RT_ERROR;
  145. }
  146. tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO);
  147. if (tx_sem == RT_NULL)
  148. {
  149. LOG_E("Init tx_sem failed.");
  150. uart_result = RT_FALSE;
  151. return -RT_ERROR;
  152. }
  153. /* reinitialize */
  154. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  155. config.baud_rate = BAUD_RATE_115200;
  156. config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
  157. config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
  158. #ifdef RT_SERIAL_USING_DMA
  159. config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
  160. #endif
  161. rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
  162. result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);
  163. if (result != RT_EOK)
  164. {
  165. LOG_E("Open uart device failed.");
  166. uart_result = RT_FALSE;
  167. return -RT_ERROR;
  168. }
  169. rt_int32_t timeout = 5000;
  170. rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
  171. /* set receive callback function */
  172. result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion);
  173. if (result != RT_EOK)
  174. {
  175. goto __exit;
  176. }
  177. result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate);
  178. if (result != RT_EOK)
  179. {
  180. goto __exit;
  181. }
  182. thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10);
  183. thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10);
  184. if (thread_send != RT_NULL && thread_recv != RT_NULL)
  185. {
  186. rt_thread_startup(thread_recv);
  187. rt_thread_startup(thread_send);
  188. }
  189. else
  190. {
  191. result = -RT_ERROR;
  192. goto __exit;
  193. }
  194. while (1)
  195. {
  196. if (uart_result != RT_TRUE)
  197. {
  198. LOG_E("The test for uart dma is failure.");
  199. result = -RT_ERROR;
  200. goto __exit;
  201. }
  202. if (uart_over_flag == RT_TRUE)
  203. {
  204. goto __exit;
  205. }
  206. /* waiting for test over */
  207. rt_thread_mdelay(5);
  208. }
  209. __exit:
  210. if (tx_sem)
  211. rt_sem_delete(tx_sem);
  212. if (rx_sem)
  213. rt_sem_delete(rx_sem);
  214. rt_device_close(&serial->parent);
  215. rt_thread_mdelay(5);
  216. uart_over_flag = RT_FALSE;
  217. return result;
  218. }
  219. static void tc_uart_api(void)
  220. {
  221. rt_uint32_t count = 0;
  222. rt_uint16_t num = 0;
  223. rt_uint32_t i = 0;
  224. for (i = 1; i < 10; i++)
  225. {
  226. if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
  227. LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_TXBUF_SIZE * i + i % 2, ++count);
  228. else
  229. {
  230. LOG_E("uart test error");
  231. goto __exit;
  232. }
  233. }
  234. for (i = 1; i < 10; i++)
  235. {
  236. if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
  237. LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", RT_SERIAL_TC_RXBUF_SIZE * i + i % 2, ++count);
  238. else
  239. {
  240. LOG_E("uart test error");
  241. goto __exit;
  242. }
  243. }
  244. srand(rt_tick_get());
  245. while (RT_SERIAL_TC_SEND_ITERATIONS - count)
  246. {
  247. num = (rand() % 1000) + 1;
  248. if (uart_api(num) == RT_EOK)
  249. LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count);
  250. else
  251. {
  252. LOG_E("uart test error");
  253. break;
  254. }
  255. }
  256. __exit:
  257. uassert_true(uart_result == RT_TRUE);
  258. }
  259. static rt_err_t utest_tc_init(void)
  260. {
  261. LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
  262. return RT_EOK;
  263. }
  264. static rt_err_t utest_tc_cleanup(void)
  265. {
  266. tx_sem = RT_NULL;
  267. uart_result = RT_TRUE;
  268. uart_over_flag = RT_FALSE;
  269. rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  270. while (rt_device_close(uart_dev) != -RT_ERROR);
  271. return RT_EOK;
  272. }
  273. static void testcase(void)
  274. {
  275. UTEST_UNIT_RUN(tc_uart_api);
  276. }
  277. UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txnb", utest_tc_init, utest_tc_cleanup, 30);
  278. #endif