uart_rxnb_txnb.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Copyright (c) 2006-2019, 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. #define TC_UART_DEVICE_NAME "uart2"
  15. #define TC_UART_SEND_TIMES 100
  16. #ifdef UTEST_SERIAL_TC
  17. #define TEST_UART_NAME TC_UART_DEVICE_NAME
  18. static struct rt_serial_device *serial;
  19. static rt_sem_t tx_sem;
  20. static rt_sem_t rx_sem;
  21. static rt_uint8_t uart_over_flag;
  22. static rt_bool_t uart_result = RT_TRUE;
  23. static rt_err_t uart_find(void)
  24. {
  25. serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME);
  26. if (serial == RT_NULL)
  27. {
  28. LOG_E("find %s device failed!\n", TEST_UART_NAME);
  29. return -RT_ERROR;
  30. }
  31. return RT_EOK;
  32. }
  33. static rt_err_t uart_tx_completion(rt_device_t device, void *buffer)
  34. {
  35. rt_sem_release(tx_sem);
  36. return RT_EOK;
  37. }
  38. static rt_err_t uart_rx_indicate(rt_device_t device, rt_size_t size)
  39. {
  40. rt_sem_release(rx_sem);
  41. return RT_EOK;
  42. }
  43. static void uart_send_entry(void *parameter)
  44. {
  45. rt_uint8_t *uart_write_buffer;
  46. rt_uint16_t send_len, len = 0;
  47. rt_err_t result;
  48. rt_uint32_t i = 0;
  49. send_len = *(rt_uint16_t *)parameter;
  50. /* assign send buffer */
  51. uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
  52. if (uart_write_buffer == RT_NULL)
  53. {
  54. LOG_E("Without spare memory for uart dma!");
  55. uart_result = RT_FALSE;
  56. return;
  57. }
  58. rt_memset(uart_write_buffer, 0, send_len);
  59. for (i = 0; i < send_len; i++)
  60. {
  61. uart_write_buffer[i] = (rt_uint8_t)i;
  62. }
  63. /* send buffer */
  64. while (send_len - len)
  65. {
  66. len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
  67. result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
  68. if (result != RT_EOK)
  69. {
  70. LOG_E("take sem err in send.");
  71. }
  72. }
  73. rt_free(uart_write_buffer);
  74. }
  75. static void uart_rec_entry(void *parameter)
  76. {
  77. rt_uint16_t rev_len;
  78. rev_len = *(rt_uint16_t *)parameter;
  79. rt_uint8_t *ch;
  80. ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
  81. rt_int32_t cnt, i;
  82. rt_uint8_t last_old_data;
  83. rt_bool_t fisrt_flag = RT_TRUE;
  84. rt_uint32_t all_receive_length = 0;
  85. while (1)
  86. {
  87. rt_err_t result;
  88. result = rt_sem_take(rx_sem, RT_WAITING_FOREVER);
  89. if (result != RT_EOK)
  90. {
  91. LOG_E("take sem err in recv.");
  92. }
  93. cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len);
  94. if (cnt == 0)
  95. {
  96. continue;
  97. }
  98. if (fisrt_flag != RT_TRUE)
  99. {
  100. if ((rt_uint8_t)(last_old_data + 1) != ch[0])
  101. {
  102. LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]);
  103. uart_result = RT_FALSE;
  104. rt_free(ch);
  105. return;
  106. }
  107. }
  108. else
  109. {
  110. fisrt_flag = RT_FALSE;
  111. }
  112. for (i = 0; i < cnt - 1; i++)
  113. {
  114. if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1])
  115. {
  116. LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]);
  117. uart_result = RT_FALSE;
  118. rt_free(ch);
  119. return;
  120. }
  121. }
  122. all_receive_length += cnt;
  123. if (all_receive_length >= rev_len)
  124. break;
  125. else
  126. last_old_data = ch[cnt - 1];
  127. }
  128. rt_free(ch);
  129. uart_over_flag = RT_TRUE;
  130. }
  131. static rt_err_t uart_api(rt_uint16_t test_buf)
  132. {
  133. rt_thread_t thread_send = RT_NULL;
  134. rt_thread_t thread_recv = RT_NULL;
  135. rt_err_t result = RT_EOK;
  136. uart_over_flag = RT_FALSE;
  137. result = uart_find();
  138. if (result != RT_EOK)
  139. {
  140. return -RT_ERROR;
  141. }
  142. rx_sem = rt_sem_create("rx_sem", 0, RT_IPC_FLAG_PRIO);
  143. if (rx_sem == RT_NULL)
  144. {
  145. LOG_E("Init rx_sem failed.");
  146. uart_result = RT_FALSE;
  147. return -RT_ERROR;
  148. }
  149. tx_sem = rt_sem_create("tx_sem", 0, RT_IPC_FLAG_PRIO);
  150. if (tx_sem == RT_NULL)
  151. {
  152. LOG_E("Init tx_sem failed.");
  153. uart_result = RT_FALSE;
  154. return -RT_ERROR;
  155. }
  156. /* reinitialize */
  157. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  158. config.baud_rate = BAUD_RATE_115200;
  159. config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
  160. config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
  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. /* set receive callback function */
  170. result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion);
  171. if (result != RT_EOK)
  172. {
  173. goto __exit;
  174. }
  175. result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate);
  176. if (result != RT_EOK)
  177. {
  178. goto __exit;
  179. }
  180. thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 5, 10);
  181. thread_send = rt_thread_create("uart_send", uart_send_entry, &test_buf, 1024, RT_THREAD_PRIORITY_MAX - 4, 10);
  182. if (thread_send != RT_NULL && thread_recv != RT_NULL)
  183. {
  184. rt_thread_startup(thread_recv);
  185. rt_thread_startup(thread_send);
  186. }
  187. else
  188. {
  189. result = -RT_ERROR;
  190. goto __exit;
  191. }
  192. while (1)
  193. {
  194. if (uart_result != RT_TRUE)
  195. {
  196. LOG_E("The test for uart dma is failure.");
  197. result = -RT_ERROR;
  198. goto __exit;
  199. }
  200. if (uart_over_flag == RT_TRUE)
  201. {
  202. goto __exit;
  203. }
  204. /* waiting for test over */
  205. rt_thread_mdelay(5);
  206. }
  207. __exit:
  208. if (tx_sem)
  209. rt_sem_delete(tx_sem);
  210. if (rx_sem)
  211. rt_sem_delete(rx_sem);
  212. rt_device_close(&serial->parent);
  213. return result;
  214. }
  215. static void tc_uart_api(void)
  216. {
  217. rt_uint32_t times = 0;
  218. rt_uint16_t num = 0;
  219. while (TC_UART_SEND_TIMES - times)
  220. {
  221. num = (rand() % 1000) + 1;
  222. if(uart_api(num) == RT_EOK)
  223. LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times);
  224. else
  225. {
  226. LOG_E("uart test error");
  227. break;
  228. }
  229. }
  230. uassert_true(uart_over_flag == RT_TRUE);
  231. }
  232. static rt_err_t utest_tc_init(void)
  233. {
  234. LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
  235. return RT_EOK;
  236. }
  237. static rt_err_t utest_tc_cleanup(void)
  238. {
  239. tx_sem = RT_NULL;
  240. uart_result = RT_TRUE;
  241. uart_over_flag = RT_FALSE;
  242. return RT_EOK;
  243. }
  244. static void testcase(void)
  245. {
  246. UTEST_UNIT_RUN(tc_uart_api);
  247. }
  248. UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_rxnb_txnb", utest_tc_init, utest_tc_cleanup, 30);
  249. #endif