uart_timeout_rxb.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 RX Timeout Test
  12. *
  13. * Test Objectives:
  14. * - Validate blocking receive timeout behavior while TX operates non-blocking
  15. * - Verify APIs: rt_device_find, rt_device_control(RT_SERIAL_CTRL_SET_RX_TIMEOUT / _TX_FLUSH),
  16. * rt_device_open with RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING,
  17. * rt_device_write, rt_device_read
  18. *
  19. * Test Scenarios:
  20. * - **Scenario 1 (RX Timeout Sweep / tc_uart_api):**
  21. * 1. Reconfigure UART buffers (optional DMA ping buffer) and open in RX blocking / TX non-blocking mode.
  22. * 2. Allocate reusable TX buffer and iterate `RT_SERIAL_TC_SEND_ITERATIONS` times.
  23. * 3. For each iteration, randomize burst length (1024~2047 bytes), program RX timeout, transmit payload,
  24. * then read back and ensure received size reflects timeout truncation.
  25. * 4. Flush TX FIFO and delay to allow residual bytes to drain before next iteration.
  26. *
  27. * Verification Metrics:
  28. * - Each receive length lies within `[rx_timeout_send_size - 70, send_size - 80]`.
  29. * - Transmission always completes full burst; overall loop exits with RT_EOK and device closes successfully.
  30. *
  31. * Dependencies:
  32. * - Requires `RT_UTEST_SERIAL_V2` with UART loopback (`RT_SERIAL_TC_DEVICE_NAME` TX shorted to RX).
  33. * - Serial driver must support RX timeout control and optional DMA ping buffer configuration.
  34. * - Random number generator and system tick used for timeout computation.
  35. *
  36. * Expected Results:
  37. * - No assertions triggered; log traces show per-iteration timeout measurements.
  38. * - Utest framework prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_timeout_rxb)`.
  39. */
  40. #include <rtthread.h>
  41. #include "utest.h"
  42. #include <rtdevice.h>
  43. #include <stdlib.h>
  44. #ifdef RT_UTEST_SERIAL_V2
  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 rx_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 rx_timeout_send_size = send_size - send_size / 3;
  60. rt_int32_t rx_timeout = rt_tick_from_millisecond(0.0868 * rx_timeout_send_size + 1);
  61. rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
  62. rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
  63. if (size != send_size)
  64. {
  65. LOG_E("size [%4d], send_size [%4d]", size, send_size);
  66. return -RT_ERROR;
  67. }
  68. readSize = rt_device_read(&serial->parent, 0, uart_write_buffer, size);
  69. if (readSize < (rx_timeout_send_size - 70) || readSize > (send_size - 80))
  70. {
  71. LOG_E("readSize [%4d], rx_timeout_send_size [%4d]", readSize, rx_timeout_send_size);
  72. return -RT_ERROR;
  73. }
  74. rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
  75. /* Waiting for rx to complete reception */
  76. rt_thread_mdelay(0.0868 * (send_size / 3));
  77. LOG_I("rx timeout send_size [%4d]", send_size);
  78. return RT_EOK;
  79. }
  80. static rt_bool_t uart_api()
  81. {
  82. rt_err_t result = RT_EOK;
  83. result = uart_find();
  84. if (result != RT_EOK)
  85. {
  86. return RT_FALSE;
  87. }
  88. /* Reinitialize */
  89. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  90. config.baud_rate = BAUD_RATE_115200;
  91. config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
  92. config.tx_bufsz = 2048;
  93. #ifdef RT_SERIAL_USING_DMA
  94. config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
  95. #endif
  96. rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
  97. result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);
  98. if (result != RT_EOK)
  99. {
  100. LOG_E("Open uart device failed.");
  101. return RT_FALSE;
  102. }
  103. rt_uint8_t *uart_write_buffer;
  104. rt_uint32_t i;
  105. uart_write_buffer = (rt_uint8_t *)rt_malloc(2048);
  106. for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
  107. {
  108. srand(rt_tick_get());
  109. if (RT_EOK != rx_timeout_test_item(uart_write_buffer, 1024 + (rand() % 1024)))
  110. {
  111. LOG_E("test_item failed.");
  112. result = -RT_ERROR;
  113. goto __exit;
  114. }
  115. }
  116. __exit:
  117. rt_free(uart_write_buffer);
  118. rt_device_close(&serial->parent);
  119. rt_thread_mdelay(5);
  120. return result == RT_EOK ? RT_TRUE : RT_FALSE;
  121. }
  122. static void tc_uart_api(void)
  123. {
  124. uassert_true(uart_api() == RT_TRUE);
  125. }
  126. static rt_err_t utest_tc_init(void)
  127. {
  128. LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
  129. return RT_EOK;
  130. }
  131. static rt_err_t utest_tc_cleanup(void)
  132. {
  133. rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  134. while (rt_device_close(uart_dev) != -RT_ERROR);
  135. return RT_EOK;
  136. }
  137. static void testcase(void)
  138. {
  139. UTEST_UNIT_RUN(tc_uart_api);
  140. }
  141. UTEST_TC_EXPORT(testcase, "components.drivers.serial.v2.uart_timeout_rxb", utest_tc_init, utest_tc_cleanup, 30);
  142. #endif /* TC_UART_USING_TC */