uart_get_unread_bytes_count.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 Unread Bytes Count Test
  12. *
  13. * Test Objectives:
  14. * - Validate query of unread RX bytes and flush interaction in non-blocking receive mode
  15. * - Verify APIs: rt_device_find, rt_device_control(RT_DEVICE_CTRL_CONFIG / RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT / RT_SERIAL_CTRL_RX_FLUSH),
  16. * rt_device_open with RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING,
  17. * rt_device_write
  18. *
  19. * Test Scenarios:
  20. * - **Scenario 1 (Unread Count Verification / tc_uart_api):**
  21. * 1. Configure UART buffers and send varying payload lengths, some exceeding RX buffer capacity.
  22. * 2. After each transfer, query unread byte count and ensure it saturates at `min(send_size, RT_SERIAL_TC_RXBUF_SIZE)`.
  23. * 3. Flush RX buffer and verify unread count resets to zero before next iteration.
  24. *
  25. * Verification Metrics:
  26. * - `RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT` returns expected length; subsequent flush yields zero.
  27. * - All iterations covering large and random payloads complete with RT_EOK.
  28. *
  29. * Dependencies:
  30. * - Requires `RT_UTEST_SERIAL_V2`, RX count control support, and loopback wiring on `RT_SERIAL_TC_DEVICE_NAME`.
  31. * - Optional DMA ping buffer configuration honored.
  32. *
  33. * Expected Results:
  34. * - Test ends without assertions; logs may remain silent unless failures occur.
  35. * - Utest harness prints `[ PASSED ] [ result ] testcase (components.drivers.serial.v2.uart_get_unread_bytes_count)`.
  36. */
  37. #include <rtthread.h>
  38. #include "utest.h"
  39. #include <rtdevice.h>
  40. #include <stdlib.h>
  41. /* */
  42. #ifdef RT_UTEST_SERIAL_V2
  43. static struct rt_serial_device *serial;
  44. static rt_uint8_t uart_over_flag = RT_FALSE;
  45. static rt_err_t uart_find(void)
  46. {
  47. serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  48. if (serial == RT_NULL)
  49. {
  50. LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
  51. return -RT_ERROR;
  52. }
  53. return RT_EOK;
  54. }
  55. static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size)
  56. {
  57. rt_uint32_t old_tick;
  58. rt_ssize_t send_len;
  59. rt_ssize_t buf_data_len;
  60. send_len = rt_device_write(&serial->parent, 0, uart_write_buffer, size);
  61. if (size > RT_SERIAL_TC_RXBUF_SIZE)
  62. {
  63. size = RT_SERIAL_TC_RXBUF_SIZE;
  64. }
  65. rt_thread_delay(5);
  66. rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len);
  67. if (size != buf_data_len)
  68. {
  69. return -RT_ERROR;
  70. }
  71. rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
  72. rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len);
  73. if (0 != buf_data_len)
  74. {
  75. return -RT_ERROR;
  76. }
  77. return RT_EOK;
  78. }
  79. static rt_bool_t uart_api()
  80. {
  81. rt_err_t result = RT_EOK;
  82. result = uart_find();
  83. if (result != RT_EOK)
  84. {
  85. return RT_FALSE;
  86. }
  87. /* Reinitialize */
  88. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  89. config.baud_rate = BAUD_RATE_115200;
  90. config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
  91. config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
  92. #ifdef RT_SERIAL_USING_DMA
  93. config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
  94. #endif
  95. rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
  96. result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
  97. if (result != RT_EOK)
  98. {
  99. LOG_E("Open uart device failed.");
  100. return RT_FALSE;
  101. }
  102. rt_uint8_t *uart_write_buffer;
  103. rt_uint32_t i;
  104. uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_TXBUF_SIZE * 5 + 1);
  105. srand(rt_tick_get());
  106. for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
  107. {
  108. if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5)))
  109. {
  110. result = -RT_ERROR;
  111. goto __exit;
  112. }
  113. if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5)))
  114. {
  115. result = -RT_ERROR;
  116. goto __exit;
  117. }
  118. }
  119. __exit:
  120. rt_free(uart_write_buffer);
  121. rt_device_close(&serial->parent);
  122. rt_thread_mdelay(5);
  123. return result == RT_EOK ? RT_TRUE : RT_FALSE;
  124. }
  125. static void tc_uart_api(void)
  126. {
  127. uassert_true(uart_api() == RT_TRUE);
  128. }
  129. static rt_err_t utest_tc_init(void)
  130. {
  131. return RT_EOK;
  132. }
  133. static rt_err_t utest_tc_cleanup(void)
  134. {
  135. rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
  136. while (rt_device_close(uart_dev) != -RT_ERROR);
  137. return RT_EOK;
  138. }
  139. static void testcase(void)
  140. {
  141. UTEST_UNIT_RUN(tc_uart_api);
  142. }
  143. UTEST_TC_EXPORT(testcase, "components.drivers.serial.v2.uart_get_unread_bytes_count", utest_tc_init, utest_tc_cleanup, 30);
  144. #endif /* TC_UART_USING_TC */