uart_timeout_txb.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2006-2025 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-11-13 CYFS Add standardized utest documentation block
  9. */
  10. /**
  11. * Test Case Name: UART Blocking TX Timeout Test
  12. *
  13. * Test Objectives:
  14. * - Validate blocking transmit timeout handling when RX operates non-blocking
  15. * - Verify APIs: rt_device_find, rt_device_control(RT_SERIAL_CTRL_SET_TX_TIMEOUT / _TX_FLUSH),
  16. * rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING, rt_device_write
  17. *
  18. * Test Scenarios:
  19. * - **Scenario 1 (TX Timeout Sweep / tc_uart_api):**
  20. * 1. Configure UART buffers and open the device in RX non-blocking / TX blocking mode.
  21. * 2. Allocate a reusable TX buffer and iterate `RT_SERIAL_TC_SEND_ITERATIONS` times.
  22. * 3. For each iteration, randomize burst length (1024~2047 bytes), set expected TX timeout,
  23. * issue write, and ensure returned write size falls into tolerated range.
  24. * 4. Flush TX FIFO and delay to allow loopback RX to complete reception.
  25. *
  26. * Verification Metrics:
  27. * - Each write returns size within `[tx_timeout_send_size - 70, send_size - 80]`.
  28. * - No allocation failures; all iterations exit via RT_EOK and device closes cleanly.
  29. *
  30. * Dependencies:
  31. * - Requires `RT_UTEST_SERIAL_V2` enabled and loopback wiring of `RT_SERIAL_TC_DEVICE_NAME`.
  32. * - Excludes configurations with `BSP_UART2_TX_USING_DMA` (DMA write timeout unsupported).
  33. * - Needs random number generator and system tick for duration calculations.
  34. *
  35. * Expected Results:
  36. * - Test completes without assertion failures; logs show sequence of timeout send sizes.
  37. * - Utest framework prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_timeout_txb)`.
  38. */
  39. #include <rtthread.h>
  40. #include "utest.h"
  41. #include <rtdevice.h>
  42. #include <stdlib.h>
  43. #ifdef RT_UTEST_SERIAL_V2
  44. #ifndef BSP_UART2_TX_USING_DMA
  45. static struct rt_serial_device *serial;
  46. static rt_err_t uart_find(void)
  47. {
  48. serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  49. if (serial == RT_NULL)
  50. {
  51. LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
  52. return -RT_ERROR;
  53. }
  54. return RT_EOK;
  55. }
  56. static rt_err_t tx_timeout_test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
  57. {
  58. rt_uint32_t readSize = 0;
  59. rt_int32_t tx_timeout_send_size = send_size - send_size / 3;
  60. rt_int32_t tx_timeout = rt_tick_from_millisecond(0.0868 * tx_timeout_send_size + 1);
  61. rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
  62. rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
  63. if (size < (tx_timeout_send_size - 70) || size > (send_size - 80))
  64. {
  65. LOG_E("size [%4d], send_size [%4d]", size, tx_timeout_send_size);
  66. return -RT_ERROR;
  67. }
  68. rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
  69. /* Waiting for rx to complete reception */
  70. rt_thread_mdelay(0.0868 * (send_size / 3));
  71. LOG_I("tx timeout send_size [%4d]", send_size);
  72. return RT_EOK;
  73. }
  74. static rt_bool_t uart_api()
  75. {
  76. rt_err_t result = RT_EOK;
  77. result = uart_find();
  78. if (result != RT_EOK)
  79. {
  80. return RT_FALSE;
  81. }
  82. /* Reinitialize */
  83. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  84. config.baud_rate = BAUD_RATE_115200;
  85. config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
  86. config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
  87. rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
  88. result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
  89. if (result != RT_EOK)
  90. {
  91. LOG_E("Open uart device failed.");
  92. return RT_FALSE;
  93. }
  94. rt_uint8_t *uart_write_buffer;
  95. rt_uint32_t i;
  96. uart_write_buffer = (rt_uint8_t *)rt_malloc(2048);
  97. for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
  98. {
  99. srand(rt_tick_get());
  100. if (RT_EOK != tx_timeout_test_item(uart_write_buffer, 1024 + (rand() % 1024)))
  101. {
  102. LOG_E("test_item failed.");
  103. result = -RT_ERROR;
  104. goto __exit;
  105. }
  106. }
  107. __exit:
  108. rt_free(uart_write_buffer);
  109. rt_device_close(&serial->parent);
  110. rt_thread_mdelay(5);
  111. return result == RT_EOK ? RT_TRUE : RT_FALSE;
  112. }
  113. static void tc_uart_api(void)
  114. {
  115. uassert_true(uart_api() == RT_TRUE);
  116. }
  117. static rt_err_t utest_tc_init(void)
  118. {
  119. LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
  120. return RT_EOK;
  121. }
  122. static rt_err_t utest_tc_cleanup(void)
  123. {
  124. rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  125. while (rt_device_close(uart_dev) != -RT_ERROR);
  126. return RT_EOK;
  127. }
  128. static void testcase(void)
  129. {
  130. UTEST_UNIT_RUN(tc_uart_api);
  131. }
  132. UTEST_TC_EXPORT(testcase, "components.drivers.serial.v2.uart_timeout_txb", utest_tc_init, utest_tc_cleanup, 30);
  133. #endif /* BSP_UART2_TX_USING_DMA */
  134. #endif /* TC_UART_USING_TC */