uart_overflow_rxb_txb.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. *
  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_uint8_t uart_over_flag = RT_FALSE;
  17. static rt_bool_t uart_result = RT_TRUE;
  18. static rt_err_t uart_find(void)
  19. {
  20. serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  21. if (serial == RT_NULL)
  22. {
  23. LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
  24. return -RT_ERROR;
  25. }
  26. return RT_EOK;
  27. }
  28. static void uart_send_entry(void *parameter)
  29. {
  30. rt_uint32_t send_len;
  31. rt_uint8_t *uart_write_buffer = RT_NULL;
  32. rt_uint32_t i = 0;
  33. send_len = *(rt_uint32_t *)parameter;
  34. /* assign send buffer */
  35. uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
  36. if (uart_write_buffer == RT_NULL)
  37. {
  38. LOG_E("Without spare memory for uart dma!");
  39. uart_result = RT_FALSE;
  40. return;
  41. }
  42. rt_memset(uart_write_buffer, 0, send_len);
  43. for (i = 0; i < send_len; i++)
  44. {
  45. uart_write_buffer[i] = (rt_uint8_t)i;
  46. }
  47. /* send buffer */
  48. if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len)
  49. {
  50. LOG_E("device write failed\r\n");
  51. }
  52. rt_free(uart_write_buffer);
  53. }
  54. static void uart_rec_entry(void *parameter)
  55. {
  56. rt_uint32_t rev_len;
  57. rt_uint8_t *uart_write_buffer;
  58. rt_int32_t cnt, i;
  59. rev_len = *(rt_uint32_t *)parameter;
  60. uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (rev_len + 1));
  61. while (1)
  62. {
  63. cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE);
  64. if (cnt != RT_SERIAL_TC_RXBUF_SIZE)
  65. {
  66. uart_result = RT_FALSE;
  67. rt_free(uart_write_buffer);
  68. return;
  69. }
  70. #ifdef RT_SERIAL_BUF_STRATEGY_DROP
  71. for (i = 0; i < cnt; i++)
  72. {
  73. if (uart_write_buffer[i] != i)
  74. {
  75. LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], i);
  76. uart_result = RT_FALSE;
  77. rt_free(uart_write_buffer);
  78. return;
  79. }
  80. }
  81. #else
  82. for (i = cnt - 1; i >= 0; i--)
  83. {
  84. if (uart_write_buffer[i] != ((rev_len - (cnt - i)) % (UINT8_MAX + 1)))
  85. {
  86. LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], ((rev_len - (cnt - i)) % (UINT8_MAX + 1)));
  87. uart_result = RT_FALSE;
  88. rt_free(uart_write_buffer);
  89. return;
  90. }
  91. }
  92. #endif /* RT_SERIAL_BUF_STRATEGY_DROP */
  93. break;
  94. }
  95. rt_free(uart_write_buffer);
  96. uart_over_flag = RT_TRUE;
  97. }
  98. static rt_err_t uart_api(rt_uint32_t length)
  99. {
  100. rt_thread_t thread_send = RT_NULL;
  101. rt_thread_t thread_recv = RT_NULL;
  102. rt_err_t result = RT_EOK;
  103. uart_over_flag = RT_FALSE;
  104. result = uart_find();
  105. if (result != RT_EOK)
  106. {
  107. return -RT_ERROR;
  108. }
  109. /* Reinitialize */
  110. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  111. config.baud_rate = BAUD_RATE_115200;
  112. config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
  113. config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
  114. #ifdef RT_SERIAL_USING_DMA
  115. config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
  116. #endif
  117. rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
  118. result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
  119. if (result != RT_EOK)
  120. {
  121. LOG_E("Open uart device failed.");
  122. uart_result = RT_FALSE;
  123. return -RT_ERROR;
  124. }
  125. rt_int32_t timeout = 5000;
  126. rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
  127. thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 4, 10);
  128. thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 5, 10);
  129. if ((thread_send != RT_NULL) && (thread_recv != RT_NULL))
  130. {
  131. rt_thread_startup(thread_send);
  132. /* waiting for data transmission to complete*/
  133. rt_thread_mdelay(length * 0.0868 + 10);
  134. rt_thread_startup(thread_recv);
  135. }
  136. else
  137. {
  138. result = -RT_ERROR;
  139. goto __exit;
  140. }
  141. while (1)
  142. {
  143. if (uart_result != RT_TRUE)
  144. {
  145. LOG_E("The test for uart dma is failure.");
  146. result = -RT_ERROR;
  147. goto __exit;
  148. }
  149. if (uart_over_flag == RT_TRUE)
  150. {
  151. goto __exit;
  152. }
  153. /* waiting for test over */
  154. rt_thread_mdelay(5);
  155. }
  156. __exit:
  157. rt_device_close(&serial->parent);
  158. rt_thread_mdelay(5);
  159. return result;
  160. }
  161. static void tc_uart_api(void)
  162. {
  163. rt_uint32_t count = 0;
  164. rt_uint16_t num = 0;
  165. rt_uint32_t i = 0;
  166. for (i = 1; i < 10; i++)
  167. {
  168. if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
  169. 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);
  170. else
  171. {
  172. LOG_E("uart test error");
  173. goto __exit;
  174. }
  175. }
  176. for (i = 1; i < 10; i++)
  177. {
  178. if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
  179. 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);
  180. else
  181. {
  182. LOG_E("uart test error");
  183. goto __exit;
  184. }
  185. }
  186. srand(rt_tick_get());
  187. while (RT_SERIAL_TC_SEND_ITERATIONS - count)
  188. {
  189. num = (rand() % RT_SERIAL_TC_RXBUF_SIZE) + 1;
  190. if (uart_api(num + RT_SERIAL_TC_RXBUF_SIZE) == RT_EOK)
  191. LOG_I("data_lens [%3d], it is correct to read and write data. [%d] count testing.", num, ++count);
  192. else
  193. {
  194. LOG_E("uart test error");
  195. break;
  196. }
  197. }
  198. __exit:
  199. uassert_true(uart_result == RT_TRUE);
  200. }
  201. static rt_err_t utest_tc_init(void)
  202. {
  203. LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
  204. return RT_EOK;
  205. }
  206. static rt_err_t utest_tc_cleanup(void)
  207. {
  208. uart_result = RT_TRUE;
  209. uart_over_flag = RT_FALSE;
  210. rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  211. while (rt_device_close(uart_dev) != -RT_ERROR);
  212. return RT_EOK;
  213. }
  214. static void testcase(void)
  215. {
  216. UTEST_UNIT_RUN(tc_uart_api);
  217. }
  218. UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_overflow_rxb_txb", utest_tc_init, utest_tc_cleanup, 30);
  219. #endif /* TC_UART_USING_TC */