summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorryancw <[email protected]>2024-09-04 10:39:10 +0800
committerRbb666 <[email protected]>2025-05-16 09:42:11 +0800
commitac8fba0129f98b5c6a7c6caaa55538a53b370db2 (patch)
treeff4cfe35207900dba802b879da2f244a3adf5f5b /examples
parentbf96f99d6bc3dfa3c7c9230d1b8e4415c02f19f0 (diff)
[drivers][serial_v2]允许阻塞接收超过rx缓冲区大小的数据、增加超时时间、flush、获取缓冲区数据长度命令、数据溢出逻辑修复、稳定性细节优化、添加更多serial_v2测试用例
[components][serial_v2] 优化txflush逻辑、对tx的activated做中断保护 [components][at] at_client适配新版serial_v2 [components][at] at_server适配新版serial_v2 [components][serial_v2] 测试用例增加循环调用,format测试用例 [components][serial_v2] poll模式判断逻辑错误 [components][serial_v2] 测试用例去掉一些非必要延时 [components][serial_v2] 测试例程使用menuconfig进行配置,更新readme [components][at_client] at_client_getchar返回值错误、at_client解析线程优先级错误设置 [components][at] 错误码应该返回负值 [components][serial_v2] TCFLSH和FIONREAD完善、control函数增加错误返回值 [components][serial_v2] RT_SERIAL_CTRL_GET_RX_DATA_LEN更改为RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT [utest][serial_v2] TC_UART_SEND_TIMES替换为RT_SERIAL_TC_SEND_ITERATIONS [components][serial_v2] FIONREAD参数应该是无符号类型 [utest][serial_v2] 完善测试用例 [components][serial_v2] 避免使用三目运算符 [components][serial_v2] 使用clang-format格式化代码 [components][serial_v2] 添加get超时时间命令 [components][serial_v2] 完善posix接口 [components][serial_v2] 阻塞接口添加阻塞时间为0时的处理逻辑、优化RX阻塞接收逻辑 [components][serial_v2] 设置超时时间命令的参数改为指针形式 [components][serial_v2] nbuf发送添加超时时间为0时的逻辑 [components][serial_v2] 完善添加测试用例 [utest][serial_v2] 修复依赖关系 [components][serial_v2] 非阻塞模式下tx_flush错误修复 [components][serial_v2] activated使用原子API [components][serial_v2] 优化DMA逻辑、没使能DMA时屏蔽DMA逻辑节约资源 [components][serial_v2] 提供写满时丢弃新数据和覆盖旧数据策略,写满丢弃策略效率更高 [components][serial_v2] 部分平台适配写满时两种策略功能 [components][serial_v2] DMA模式暂不支持丢弃新数据策略 [utest][serial_v2] 优化测试代码 [components][serial_v2] DMA模式下使用乒乓缓冲、DMA模式支持丢弃新数据策略 [utest][serial_v2] 适配DMA乒乓缓冲 [bsp][serial_v2] 部分bsp适配DMA下乒乓缓冲 [components][serial_v2] 使用spinlock替换中断,对部分结构体变量使用原子操作 [utest][serial_v2] 更新测试用例 [components][at] 适配new serialv2不再判断RTT版本号 [components][at] 删除多余的中文注释 [utest][serial_v2] 添加交叉echo示例,qemu环境下专用 [bsp][qemu] 适配串口v2并开启fifo [components][at] 修复合并导致的错误 [bsp][n32] 适配serial_v2,没有经过测试 [components][serial_v2] 格式化代码 [utest][serial_v2] 删除无意义的打印
Diffstat (limited to 'examples')
-rw-r--r--examples/utest/testcases/drivers/serial_v2/Kconfig49
-rw-r--r--examples/utest/testcases/drivers/serial_v2/README.md52
-rw-r--r--examples/utest/testcases/drivers/serial_v2/SConscript22
-rw-r--r--examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c281
-rw-r--r--examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c182
-rw-r--r--examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c171
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c38
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c85
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c135
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c150
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c150
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c145
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c31
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c88
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c251
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c112
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c121
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c109
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c123
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c221
20 files changed, 2170 insertions, 346 deletions
diff --git a/examples/utest/testcases/drivers/serial_v2/Kconfig b/examples/utest/testcases/drivers/serial_v2/Kconfig
index 3c8d480b3a..f00d7311ac 100644
--- a/examples/utest/testcases/drivers/serial_v2/Kconfig
+++ b/examples/utest/testcases/drivers/serial_v2/Kconfig
@@ -1,7 +1,50 @@
menu "Utest Serial Testcase"
-config UTEST_SERIAL_TC
- bool "Serial testcase"
- default n
+ config UTEST_SERIAL_TC
+ bool "Serial testcase"
+ default n
+
+ if UTEST_SERIAL_TC
+
+ config RT_SERIAL_TC_DEVICE_NAME
+ string "the device name for serial test"
+ default "uart2"
+
+ config RT_SERIAL_TC_RXBUF_SIZE
+ int "the rx buffer size for serial test"
+ default 128
+
+ config RT_SERIAL_TC_TXBUF_SIZE
+ int "the tx buffer size for serial test"
+ default 128
+
+ config RT_SERIAL_TC_SEND_ITERATIONS
+ int "the number of iterations for the test routine."
+ default 100
+
+ config UTEST_SERIAL_QEMU_TC
+ bool "qemu dedicated tests"
+ default n
+
+ config UTEST_SERIAL_POSIX_TC
+ bool "Serial posix testcase"
+ default n
+ select RT_USING_DFS
+ select RT_USING_POSIX_FS
+ select RT_USING_POSIX_TERMIOS
+
+ if UTEST_SERIAL_POSIX_TC
+
+ config RT_SERIAL_POSIX_TC_DEVICE_NAME
+ string "the device name for serial posix test"
+ default "dev/uart2"
+
+ config RT_SERIAL_POSIX_TC_SEND_ITERATIONS
+ int "the number of iterations for the posix test routine."
+ default 100
+
+ endif
+
+ endif
endmenu
diff --git a/examples/utest/testcases/drivers/serial_v2/README.md b/examples/utest/testcases/drivers/serial_v2/README.md
index 3a6625f4bc..1a94c20a01 100644
--- a/examples/utest/testcases/drivers/serial_v2/README.md
+++ b/examples/utest/testcases/drivers/serial_v2/README.md
@@ -14,6 +14,14 @@
| uart_blocking_rx.c| 串口阻塞接收模式 的测试 |
| uart_nonblocking_tx.c| 串口非阻塞发送模式 的测试 |
| uart_nonblocking_rx.c | 串口非阻塞接收模式 的测试 |
+| uart_flush_rx | 刷新接收缓冲区的测试 |
+| uart_flush_txb | 阻塞模式下刷新发送缓冲区的测试 |
+| uart_flush_txnb | 非阻塞模式下刷新发送缓冲区的测试 |
+| uart_timeout_rxb_txb | 串口 发送 / 接收 超时的测试 |
+| uart_overflow_rxb_txb | 串口溢出处理的测试 |
+| uart_get_unread_bytes_count | 获取串口接收缓冲区中的数据长度的测试 |
+| uart_posix_nonblock | posix非阻塞测试 |
+| uart_posix_echo_block | posix阻塞echo测试 |
## 3、软硬件环境
@@ -77,37 +85,20 @@
需要解释的是,为什么会存在无意义的组合模式,举个例子,非阻塞模式下,肯定是不会出现POLL(轮询)方式的,因为POLL方式已经表明是阻塞方式了。
该测试用例在测试多种组合时,需要通过更改`rtconfig.h`文件对硬件模式进行静态配置。
-### 4.2 测试思路
+### 4.2 测试条件
-前四个测试用例的测试思路:
+**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。
->硬件上:**短接串口的发送TX引脚和接收RX引脚,完成自发自收的回路**。
->
->软件上:创建两个线程A和B,A为接收线程,B为发送线程,设置A线程优先级比B线程优先级高。发送线程发送随机长度(长度范围是 0 到 1000)的数据,接收线程接收到数据进行校验,数据正确则测试通过,默认测试100次。
-
-后四个测试用例的测试思路:
+大致的测试思路:
->硬件上: **不需要将TX,RX引脚进行短接**,每次只针对发送或接收中的一种进行测试,更为简单与直接
->
->软件上: 四个样例每次仅测试TX/RX中的一种引脚与一种对应的阻塞/非阻塞模式
->四种测试模式具体分为:
->>阻塞接收模式----(硬件工作模式可选: 轮询, 中断, DMA)
->>阻塞发送模式----(硬件工作模式可选: 轮询, 中断, DMA)
->>非阻塞接收模式--(硬件工作模式可选: 中断, DMA)
->>非阻塞发送模式--(硬件工作模式可选: 中断, DMA)
->
->其中阻塞或非阻塞背后的具体硬件工作模式选择(如 轮询, 中断, DMA)需要对`rtconfig.h`文件做出配置,具体配置流程可见文章中关于
- [seril_v2硬件工作模式的选择](https://club.rt-thread.org/ask/article/b4c536303c8e2335.html "serial_v2源码分析")一节.
->
>发送测试流程 :
>>1. 先关闭串口,再以需要测试的模式打开.
->>2. 然后依次发送 UART_SEND_TIMES(默认为400) * 1024, 8, 32, 128, 512, 1024个数据.
->>3. 发送的同时记录每次发送所耗费的时钟周期与成功发送的数据数量.
->>3. 打印记录的数据,通过时钟周期来反应发送效率, 通过成功发送的数据量来反应是否产生丢包问题.
+>>2. 然后依次发送 UART_SEND_TIMES * (1000以内的随机数)个数据.
+>>3. 打印记录的数据,通过LOG日志的时钟周期来反应发送效率, 通过成功发送的数据量来反应是否产生丢包问题.
>
>接收测试流程 :
>>1. 先关闭串口,再以需要测试的模式打开.
->>2. 然后以此接收 256, 256, 256, 128, 128, 共计1024个数据
+>>2. 然后以此接收 同发送测试流程一致的 UART_SEND_TIMES *(1000以内随机数)个数据
>>3. 接收的同时记录成功接收的数据数量
>>4. 打印记录的数据, 通过现实成功接收的数据量与串口发送的数据量做对比,来验证是否出现丢包问题
@@ -119,7 +110,14 @@
RT-Thread Utestcases --->
[*] RT-Thread Utestcases --->
Utest Serial Testcase --->
- [*] Serial testcase
+ [*] Serial testcase --->
+ the device name for serial test: uart2 (选择测试的串口)
+ (128)the rx buffer size for serial test (测试串口rx缓冲区大小)
+ (128)the tx buffer size for serial test (测试串口tx缓冲区大小)
+ (100)the number of iterations for the test routine. (测试例程的迭代次数)
+ [*] Serial posix testcase --->
+ the device name for serial posix test: dev/uart2 (posix测试的串口)
+ (100)the number of iterations for the posix test routine. (posix测试例程的迭代次数)
```
## 6、使用
@@ -140,9 +138,9 @@ RT-Thread Utestcases --->
\- 在 MSH 中输入 `utest_run testcases.drivers.uart_nonblocking_tx` 运行串口非阻塞发送测试
-\- 在 MSH 中输入 `utest_run testcases.drivers.uart_nonblocking_rx` 运行串口非阻塞接收测试
+其余同理,可在函数内部查看命令。
-如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run` 运行即可将上述测试用例按序测试。
+如果仅仅配置了 `Serial testcase` 相关的测试用例,则直接输入 `utest_run *` 运行即可将上述测试用例按序测试。
## 7、注意事项
@@ -152,7 +150,5 @@ RT-Thread Utestcases --->
\- 需在 MSH 中输入正确的命令行。
-\- 测试用例默认的测试数据长度范围最大为1000字节,如果接收端的缓冲区大小配置为小于1000字节时,那么在测试接收阻塞模式时,将会由于获取不了1000字节长度导致线程持续阻塞(因为测试用例是按 `recv_len` 长度去接收的,而不是按照单字节去接收的),因此建议接收端的缓冲区大小 (对应宏例如为 `BSP_UART2_RX_BUFSIZE`)设置为1024即可;当然也可按需减小测试的最大数据长度。
-
\- 该测试用例需要结合硬件具体的工作模式(POLL 、INT、DMA)进行测试,而硬件工作模式只能选择一种,因此需要在 `rtconfig.h` 中对串口相应的宏进行配置,来选择不同的工作模式去进行测试。
diff --git a/examples/utest/testcases/drivers/serial_v2/SConscript b/examples/utest/testcases/drivers/serial_v2/SConscript
index a7438e3a32..7ef99d20b7 100644
--- a/examples/utest/testcases/drivers/serial_v2/SConscript
+++ b/examples/utest/testcases/drivers/serial_v2/SConscript
@@ -2,19 +2,17 @@ Import('rtconfig')
from building import *
cwd = GetCurrentDir()
-src = Split('''
-uart_rxb_txnb.c
-uart_rxb_txb.c
-uart_rxnb_txb.c
-uart_rxnb_txnb.c
-uart_blocking_rx.c
-uart_blocking_tx.c
-uart_nonblocking_rx.c
-uart_nonblocking_tx.c
-''')
+src = Glob('*.c')
-CPPPATH = [cwd]
+path = [cwd]
-group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = CPPPATH)
+if GetDepend(['UTEST_SERIAL_POSIX_TC']):
+ src += Glob('posix/*.c')
+
+if GetDepend(['UTEST_SERIAL_QEMU_TC']):
+ src += Glob('qemu/*.c')
+
+group = DefineGroup('utestcases', src, depend = ['UTEST_SERIAL_TC'], CPPPATH = path)
Return('group')
+
diff --git a/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c
new file mode 100644
index 0000000000..1a0a8ec1ee
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-16 KyleChan the first version
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static int32_t serial_fd;
+static rt_uint8_t uart_over_flag;
+static rt_bool_t uart_result = RT_TRUE;
+
+static rt_err_t uart_find(void)
+{
+ serial_fd = open(RT_SERIAL_POSIX_TC_DEVICE_NAME, O_RDWR);
+ if (serial_fd == -1)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t configureSerial(int fd, int baud)
+{
+ int32_t result = 0;
+ struct termios options;
+
+ result = tcgetattr(fd, &options); // 获取当前端口的属性
+ if (result == -1)
+ return -RT_ERROR;
+
+ // 设置波特率
+ result = cfsetispeed(&options, baud); // 设置输入波特率
+ if (result == -1)
+ return -RT_ERROR;
+
+ result = cfsetospeed(&options, baud); // 设置输出波特率
+ if (result == -1)
+ return -RT_ERROR;
+
+ // 设置数据位
+ options.c_cflag &= ~PARENB; // 清除校验位,无校验
+ options.c_cflag &= ~CSTOPB; // 仅一个停止位
+ options.c_cflag &= ~CSIZE; // 清除掩码
+ options.c_cflag |= CS8; // 8位数据
+
+ // 设置无流控
+ options.c_cflag &= ~CRTSCTS; // 不使用硬件流控制
+ options.c_iflag &= ~(IXON | IXOFF | IXANY); // 不使用软件流控制
+
+ // 使能接收器和发送器
+ options.c_cflag |= CLOCAL | CREAD;
+
+ // 设置行终止符
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+
+ // 应用属性
+ result = tcsetattr(fd, TCSANOW, &options);
+ if (result == -1)
+ return -RT_ERROR;
+
+ return RT_EOK;
+}
+
+static void uart_send_entry(void *parameter)
+{
+ rt_uint8_t *uart_write_buffer;
+ rt_uint16_t send_len;
+
+ rt_uint32_t i = 0;
+ send_len = *(rt_uint16_t *)parameter;
+ /* assign send buffer */
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
+ if (uart_write_buffer == RT_NULL)
+ {
+ LOG_E("Without spare memory for uart dma!");
+ uart_result = RT_FALSE;
+ return;
+ }
+
+ rt_memset(uart_write_buffer, 0, send_len);
+
+ for (i = 0; i < send_len; i++)
+ {
+ uart_write_buffer[i] = (rt_uint8_t)i;
+ }
+ /* send buffer */
+ if (write(serial_fd, uart_write_buffer, send_len) != send_len)
+ {
+ LOG_E("device write failed\r\n");
+ }
+ rt_free(uart_write_buffer);
+}
+
+static void uart_rec_entry(void *parameter)
+{
+ rt_uint16_t rev_len;
+
+ rev_len = *(rt_uint16_t *)parameter;
+ rt_uint8_t *uart_write_buffer;
+ uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
+ rt_int32_t cnt, i;
+ rt_uint8_t last_old_data;
+ rt_bool_t fisrt_flag = RT_TRUE;
+ rt_uint32_t all_receive_length = 0;
+
+ while (1)
+ {
+ cnt = read(serial_fd, (void *)uart_write_buffer, rev_len);
+ if (cnt == 0)
+ {
+ continue;
+ }
+
+ if (fisrt_flag != RT_TRUE)
+ {
+ if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
+ {
+ LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+ }
+ else
+ {
+ fisrt_flag = RT_FALSE;
+ }
+
+ for (i = 0; i < cnt - 1; i++)
+ {
+ if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
+ {
+ LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
+
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+ }
+ all_receive_length += cnt;
+ if (all_receive_length >= rev_len)
+ break;
+ else
+ last_old_data = uart_write_buffer[cnt - 1];
+ }
+ rt_free(uart_write_buffer);
+ uart_over_flag = RT_TRUE;
+}
+
+static rt_err_t uart_api(rt_uint16_t length)
+{
+ rt_thread_t thread_send = RT_NULL;
+ rt_thread_t thread_recv = RT_NULL;
+ rt_err_t result = RT_EOK;
+ int flags = 0;
+ uart_over_flag = RT_FALSE;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+
+ result = configureSerial(serial_fd, B115200);
+ if (result == -1)
+ {
+ goto __exit;
+ }
+
+
+ flags = fcntl(serial_fd, F_GETFL, 0);
+ if (flags == -1)
+ {
+ goto __exit;
+ }
+
+ result = fcntl(serial_fd, F_SETFL, flags & ~O_NONBLOCK);
+ if (result == -1)
+ {
+ goto __exit;
+ }
+
+
+ thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10);
+ thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10);
+ if ((thread_send != RT_NULL) && (thread_recv != RT_NULL))
+ {
+ rt_thread_startup(thread_send);
+ rt_thread_startup(thread_recv);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (uart_result != RT_TRUE)
+ {
+ LOG_E("The test for uart dma is failure.");
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ if (uart_over_flag == RT_TRUE)
+ {
+ goto __exit;
+ }
+ /* waiting for test over */
+ rt_thread_mdelay(5);
+ }
+
+__exit:
+ rt_thread_mdelay(5);
+ close(serial_fd);
+ uart_over_flag = RT_FALSE;
+ return result;
+}
+
+static void tc_uart_api(void)
+{
+ rt_uint32_t times = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+
+ while (RT_SERIAL_POSIX_TC_SEND_ITERATIONS - times)
+ {
+ num = (rand() % 1000) + 1;
+ if (uart_api(num) == RT_EOK)
+ LOG_I("data_lens [%4d], it is correct to read and write data. [%d] times testing.", num, ++times);
+ else
+ {
+ LOG_E("uart test error");
+ break;
+ }
+ }
+
+__exit:
+ uassert_true(uart_result == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ close(serial_fd);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_posix_echo_block", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c
new file mode 100644
index 0000000000..3159f2d6cd
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-06-16 KyleChan the first version
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static int32_t serial_fd;
+
+static rt_err_t uart_find(void)
+{
+ serial_fd = open(RT_SERIAL_POSIX_TC_DEVICE_NAME, O_RDWR);
+ if (serial_fd == -1)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t configureSerial(int fd, int baud)
+{
+ int32_t result = 0;
+ struct termios options;
+
+ result = tcgetattr(fd, &options); // 获取当前端口的属性
+ if (result == -1)
+ return -RT_ERROR;
+
+ // 设置波特率
+ result = cfsetispeed(&options, baud); // 设置输入波特率
+ if (result == -1)
+ return -RT_ERROR;
+
+ result = cfsetospeed(&options, baud); // 设置输出波特率
+ if (result == -1)
+ return -RT_ERROR;
+
+ // 设置数据位
+ options.c_cflag &= ~PARENB; // 清除校验位,无校验
+ options.c_cflag &= ~CSTOPB; // 仅一个停止位
+ options.c_cflag &= ~CSIZE; // 清除掩码
+ options.c_cflag |= CS8; // 8位数据
+
+ // 设置无流控
+ options.c_cflag &= ~CRTSCTS; // 不使用硬件流控制
+ options.c_iflag &= ~(IXON | IXOFF | IXANY); // 不使用软件流控制
+
+ // 使能接收器和发送器
+ options.c_cflag |= CLOCAL | CREAD;
+
+ // 设置行终止符
+ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+
+ // 应用属性
+ result = tcsetattr(fd, TCSANOW, &options);
+ if (result == -1)
+ return -RT_ERROR;
+
+ return RT_EOK;
+}
+
+static rt_err_t uart_api()
+{
+ rt_err_t result = RT_EOK;
+ rt_uint8_t *uart_write_buffer;
+ rt_int32_t cnt, i, send_size;
+ int flags = 0;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+
+ result = configureSerial(serial_fd, B115200);
+ if (result == -1)
+ {
+ goto __exit;
+ }
+
+ flags = fcntl(serial_fd, F_GETFL, 0);
+ if (flags == -1)
+ {
+ goto __exit;
+ }
+
+ result = fcntl(serial_fd, F_SETFL, flags | O_NONBLOCK);
+ if (result == -1)
+ {
+ goto __exit;
+ }
+
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * 100);
+
+ for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+ {
+ send_size = 1;
+ cnt = write(serial_fd, uart_write_buffer, send_size);
+ if (cnt != send_size)
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ rt_thread_mdelay(2);
+ cnt = read(serial_fd, (void *)uart_write_buffer, send_size);
+ if (cnt != send_size)
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ send_size = rand() % 30 + 1;
+ cnt = write(serial_fd, uart_write_buffer, send_size);
+ if (cnt != send_size)
+ {
+ LOG_E("uart write failed %d %d", cnt, send_size);
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ rt_thread_mdelay(send_size * 0.0868 + 5);
+ cnt = read(serial_fd, (void *)uart_write_buffer, send_size + 1);
+ if (cnt != send_size)
+ {
+ LOG_E("uart read failed %d %d", cnt, send_size);
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ }
+
+__exit:
+ rt_thread_mdelay(5);
+ if (uart_write_buffer)
+ rt_free(uart_write_buffer);
+ close(serial_fd);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ close(serial_fd);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_posix_nonblock", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c b/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c
new file mode 100644
index 0000000000..5fdaa97793
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/qemu/uart_qemu_echo.c
@@ -0,0 +1,171 @@
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "utest.h"
+
+#define UART_SEND_TIMES 100
+#define UART_TEST_NUMBER 6
+
+
+#ifdef UTEST_SERIAL_TC
+#define echo_test_buffer_size (1024)
+
+static rt_device_t u1serial;
+static rt_device_t u2serial;
+
+static rt_uint32_t u2rx_length = 0;
+static rt_uint32_t u2tx_length = 0;
+
+static rt_uint32_t u1rx_length = 0;
+static rt_uint32_t u1tx_length = 0;
+
+static rt_uint8_t uart_over_flag = RT_FALSE;
+
+static void echo_test_u2_thread_entry(void *parameter)
+{
+ char *uart_name = "uart2";
+
+ u2serial = rt_device_find(uart_name);
+ if (!u2serial)
+ {
+ LOG_I("find %s failed!\n", uart_name);
+ return;
+ }
+
+ rt_uint8_t *rx_buffer = rt_malloc(echo_test_buffer_size);
+
+ rt_device_open(u2serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+
+ rt_ssize_t buf_datalen = 0;
+ while (1)
+ {
+ rt_device_control(u2serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen);
+ int32_t recbLen = rt_device_read(u2serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1);
+ if (recbLen > 0)
+ {
+ u2rx_length += recbLen;
+ u2tx_length += rt_device_write(u2serial, 0, rx_buffer, recbLen);
+
+ if (uart_over_flag)
+ break;
+ }
+ }
+ rt_free(rx_buffer);
+}
+
+static void echo_test_u1_thread_entry(void *parameter)
+{
+ rt_uint8_t *rx_buffer = rt_malloc(echo_test_buffer_size);
+ rt_ssize_t buf_datalen = 0;
+ while (1)
+ {
+ rt_device_control(u1serial, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_datalen);
+ int32_t recbLen = rt_device_read(u1serial, 0, rx_buffer, buf_datalen > 0 ? buf_datalen : 1);
+ if (recbLen > 0)
+ {
+ u1rx_length += recbLen;
+ if (uart_over_flag)
+ break;
+ }
+ }
+
+ rt_free(rx_buffer);
+}
+
+
+static rt_bool_t echo_test()
+{
+ rt_bool_t result = RT_TRUE;
+ char *uart_name = "uart1";
+ u1serial = rt_device_find(uart_name);
+ if (!u1serial)
+ {
+ LOG_I("find %s failed!\n", uart_name);
+ return RT_FALSE;
+ }
+
+ rt_uint8_t *tx_buffer = rt_malloc(echo_test_buffer_size);
+
+ rt_device_open(u1serial, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ rt_thread_startup(rt_thread_create("serial2", echo_test_u2_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 4, 5));
+ rt_thread_startup(rt_thread_create("serial1", echo_test_u1_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 5, 5));
+
+ uint32_t sendTotalCount = 0;
+ srand(rt_tick_get());
+ for (uint32_t count = 0; count < 1000; count++)
+ {
+ // Indefinite length of data is sent
+ uint32_t sendCount = rand() % echo_test_buffer_size;
+
+
+ u1tx_length += rt_device_write(u1serial, 0, tx_buffer, sendCount);
+ sendTotalCount += sendCount;
+
+ // Wait for the cross-send to complete
+ rt_thread_mdelay(UART_SEND_TIMES);
+
+ if (count % 50 == 0)
+ {
+ LOG_I("echo, uart2: tx: %ld, rx: %ld", u2tx_length, u2rx_length);
+ LOG_I("echo, uart1: tx: %ld, rx: %ld", u1tx_length, u1rx_length);
+ if (u2tx_length != u2rx_length || u1tx_length != u1rx_length || u2tx_length != u1tx_length)
+ {
+ LOG_I("echo test error!!!");
+ result = RT_FALSE;
+ break;
+ }
+
+ if (u2tx_length != sendTotalCount)
+ {
+ LOG_I("u2tx_length != sendTotalCount echo test error!!!");
+ result = RT_FALSE;
+ break;
+ }
+ }
+ }
+
+ uart_over_flag = RT_TRUE;
+ // Notify the thread to exit
+ rt_device_write(u1serial, 0, tx_buffer, echo_test_buffer_size);
+ rt_thread_mdelay(30);
+
+ {
+ rt_device_t uart_dev = rt_device_find("uart2");
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ }
+ {
+ rt_device_t uart_dev = rt_device_find("uart1");
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ }
+ rt_free(tx_buffer);
+ return result;
+}
+
+static void uart_test_nonblocking_tx(void)
+{
+ uassert_true(echo_test());
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ u1serial = RT_NULL;
+ u2serial = RT_NULL;
+ u2rx_length = 0;
+ u2tx_length = 0;
+ u1rx_length = 0;
+ u1tx_length = 0;
+ uart_over_flag = RT_FALSE;
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(uart_test_nonblocking_tx);
+}
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_qemu_echo", utest_tc_init, utest_tc_cleanup, 10);
+
+#endif
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c
index 2beb9e6fd9..432181c031 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c
@@ -2,53 +2,51 @@
#include <rtdevice.h>
#include "utest.h"
-#define SERIAL_UART_NAME "uart2"
-
#ifdef UTEST_SERIAL_TC
static rt_bool_t block_read(rt_device_t uart_dev)
{
rt_size_t total_length, recv_length;
- rt_uint8_t uart_read_buffer[1024], log_buffer[64];
+ char uart_read_buffer[1024], log_buffer[64];
/* make sure device is closed and reopen it */
- while(rt_device_close(uart_dev) != -RT_ERROR);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_RX_BLOCKING);
rt_sprintf(log_buffer, "\nBLOCKING READ BEGIN, PLEASE SEND SOME DATAS\n");
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
- total_length = 0;
- recv_length = 0;
- recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
+ total_length = 0;
+ recv_length = 0;
+ recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer));
total_length += recv_length;
rt_sprintf(log_buffer, "\nblock : %d bytes read, total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
- recv_length = 0;
- recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
+ recv_length = 0;
+ recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer));
total_length += recv_length;
rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
- recv_length = 0;
- recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
+ recv_length = 0;
+ recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer));
total_length += recv_length;
rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
- recv_length = 0;
- recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128);
+ recv_length = 0;
+ recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer));
total_length += recv_length;
rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
- recv_length = 0;
- recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128);
+ recv_length = 0;
+ recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, rt_strlen(log_buffer));
total_length += recv_length;
rt_sprintf(log_buffer, "\nblock : %d bytes read , total: %d \n", recv_length, total_length);
@@ -64,10 +62,10 @@ static rt_bool_t block_read(rt_device_t uart_dev)
static void uart_test_blocking_rx(void)
{
rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
+ uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
uassert_not_null(uart_dev);
- uassert_true (block_read(uart_dev));
+ uassert_true(block_read(uart_dev));
}
static rt_err_t utest_tc_init(void)
@@ -77,10 +75,8 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
- while(rt_device_close(uart_dev) != -RT_ERROR);
- rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c b/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c
index a3653079c1..a5893536ed 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c
@@ -2,82 +2,85 @@
#include <rtdevice.h>
#include "utest.h"
-#define SERIAL_UART_NAME "uart2"
-#define UART_SEND_TIMES 400
+#define UART_SEND_TIMES 100
#define UART_TEST_NUMBER 6
+
#ifdef UTEST_SERIAL_TC
static rt_bool_t block_write(rt_device_t uart_dev)
{
rt_size_t i, wr_sz, index, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER];
rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER];
- rt_uint8_t uart_write_buffer[1024];
+ char uart_write_buffer[1024];
for (i = 0; i < 1024; i++)
uart_write_buffer[i] = '0' + (i % 49);
/* make sure device is closed and reopen it */
- while(rt_device_close(uart_dev) != -RT_ERROR);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING);
LOG_D("\nBLOCKING WRITE BEGIN\n");
- rt_thread_mdelay(2000);
index = 0;
wr_sz = 0;
tick1 = rt_tick_get();
- for(i = 0; i < UART_SEND_TIMES; i++)
+ for (i = 0; i < UART_SEND_TIMES; i++)
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 1024);
- tick2 = rt_tick_get();
- total_write_num[index] = UART_SEND_TIMES * 1024;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+ total_write_num[index] = UART_SEND_TIMES * 1024;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- wr_sz = 0;
- tick1 = rt_tick_get();
+ wr_sz = 0;
+ tick1 = rt_tick_get();
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 8);
- tick2 = rt_tick_get();
- total_write_num[index] = 8;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+
+ total_write_num[index] = 8;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- wr_sz = 0;
- tick1 = rt_tick_get();
+ wr_sz = 0;
+ tick1 = rt_tick_get();
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 32);
- tick2 = rt_tick_get();
- total_write_num[index] = 32;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+
+ total_write_num[index] = 32;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- wr_sz = 0;
- tick1 = rt_tick_get();
+ wr_sz = 0;
+ tick1 = rt_tick_get();
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 128);
- tick2 = rt_tick_get();
- total_write_num[index] = 128;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+
+ total_write_num[index] = 128;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- wr_sz = 0;
- tick1 = rt_tick_get();
+ wr_sz = 0;
+ tick1 = rt_tick_get();
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 512);
- tick2 = rt_tick_get();
- total_write_num[index] = 512;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+
+ total_write_num[index] = 512;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- wr_sz = 0;
- tick1 = rt_tick_get();
+ wr_sz = 0;
+ tick1 = rt_tick_get();
wr_sz += rt_device_write(uart_dev, 0, uart_write_buffer, 1024);
- tick2 = rt_tick_get();
- total_write_num[index] = 1024;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+
+ total_write_num[index] = 1024;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- rt_thread_mdelay(1000);
LOG_D("\nBLOCKING_TX END\n");
- for(i = 0; i < index; i++)
+ for (i = 0; i < index; i++)
{
LOG_D("\nBLOCKING_MODE : write %d / %d bytes in %d ticks\n", write_num_array[i], total_write_num[i], tick_array[i]);
rt_thread_mdelay(1000);
@@ -89,10 +92,10 @@ static rt_bool_t block_write(rt_device_t uart_dev)
static void uart_test_blocking_tx(void)
{
rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
+ uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
uassert_not_null(uart_dev);
- uassert_true (block_write(uart_dev));
+ uassert_true(block_write(uart_dev));
}
static rt_err_t utest_tc_init(void)
@@ -102,10 +105,8 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
- while(rt_device_close(uart_dev) != -RT_ERROR);
- rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c
new file mode 100644
index 0000000000..7411eeaa84
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size)
+{
+ rt_device_write(&serial->parent, 0, uart_write_buffer, size);
+ rt_thread_mdelay(size * 0.0868 + 5);
+ if (1 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1))
+ {
+ LOG_E("read failed.");
+ return -RT_ERROR;
+ }
+
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
+ if (0 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1))
+ {
+ LOG_E("read failed.");
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_bool_t uart_api()
+{
+ rt_err_t result = RT_EOK;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return RT_FALSE;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ return RT_FALSE;
+ }
+
+ rt_uint8_t *uart_write_buffer;
+ rt_uint32_t i;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 1));
+
+ srand(rt_tick_get());
+ for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+ {
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5)))
+ {
+ LOG_E("test_item failed.");
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5)))
+ {
+ LOG_E("test_item failed.");
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ }
+
+__exit:
+ rt_free(uart_write_buffer);
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_rx", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c
new file mode 100644
index 0000000000..567fe3740a
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
+{
+ rt_uint32_t old_tick;
+ rt_tick_t tick_diff;
+ rt_tick_t expect_time = send_size * 0.0868;
+
+ /* In interrupt mode, ticks may be inaccurate; compensation should be applied*/
+ if (send_size > 384)
+ {
+ expect_time -= send_size / 384;
+ }
+
+ old_tick = rt_tick_get();
+ rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
+ tick_diff = rt_tick_get() - old_tick;
+
+ if (tick_diff < expect_time || tick_diff > expect_time + 10)
+ {
+ LOG_E("send_size [%4d], time required for TXB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
+ return -RT_ERROR;
+ }
+ else
+ {
+ LOG_I("send_size [%4d], time required for TXB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
+ }
+
+ return RT_EOK;
+}
+
+static rt_bool_t uart_api()
+{
+ rt_err_t result = RT_EOK;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return RT_FALSE;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE * 5 + 10;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ return RT_FALSE;
+ }
+
+ rt_uint8_t *uart_write_buffer;
+ rt_uint32_t i;
+ rt_int32_t tx_timeout = 1;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 10));
+
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
+
+ srand(rt_tick_get());
+ for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+ {
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_TXBUF_SIZE * (rand() % 6)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_TXBUF_SIZE * (rand() % 6) + 1))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_TXBUF_SIZE * 5)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ }
+
+__exit:
+ rt_free(uart_write_buffer);
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_txb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c
new file mode 100644
index 0000000000..aa086a8679
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
+{
+ rt_uint32_t old_tick;
+ rt_tick_t tick_diff;
+ rt_tick_t expect_time = send_size * 0.0868;
+
+ /* In interrupt mode, ticks may be inaccurate; compensation should be applied */
+ if (send_size > 384)
+ {
+ expect_time -= send_size / 384;
+ }
+
+ old_tick = rt_tick_get();
+ rt_uint32_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
+ tick_diff = rt_tick_get() - old_tick;
+ if (tick_diff < expect_time)
+ {
+ LOG_E("send_size [%4d], time required for TXNB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
+ return -RT_ERROR;
+ }
+ else
+ {
+ LOG_I("send_size [%4d], time required for TXNB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
+ }
+
+ return RT_EOK;
+}
+
+static rt_bool_t uart_api()
+{
+ rt_err_t result = RT_EOK;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return RT_FALSE;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_RXBUF_SIZE * 5 + 10;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ return RT_FALSE;
+ }
+
+ rt_uint8_t *uart_write_buffer;
+ rt_uint32_t i;
+ rt_int32_t tx_timeout = 1;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_RXBUF_SIZE * 5 + 10));
+
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
+
+ srand(rt_tick_get());
+ for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+ {
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * (rand() % 6)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * (rand() % 6) + 1))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ }
+
+__exit:
+ rt_free(uart_write_buffer);
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_txnb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c b/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c
new file mode 100644
index 0000000000..fc4323cc98
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+/* */
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+static rt_uint8_t uart_over_flag = RT_FALSE;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size)
+{
+ rt_uint32_t old_tick;
+ rt_ssize_t send_len;
+ rt_ssize_t buf_data_len;
+
+ send_len = rt_device_write(&serial->parent, 0, uart_write_buffer, size);
+ if (size > RT_SERIAL_TC_RXBUF_SIZE)
+ {
+ size = RT_SERIAL_TC_RXBUF_SIZE;
+ }
+
+ rt_thread_delay(5);
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len);
+ if (size != buf_data_len)
+ {
+ return -RT_ERROR;
+ }
+
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
+
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT, (void *)&buf_data_len);
+ if (0 != buf_data_len)
+ {
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_bool_t uart_api()
+{
+ rt_err_t result = RT_EOK;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return RT_FALSE;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ return RT_FALSE;
+ }
+
+ rt_uint8_t *uart_write_buffer;
+ rt_uint32_t i;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_TXBUF_SIZE * 5 + 1));
+
+ srand(rt_tick_get());
+ for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+ {
+ if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5)))
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ }
+
+
+__exit:
+ rt_free(uart_write_buffer);
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_get_unread_bytes_count", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c
index 72b5e1e332..d67a5d17ae 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_rx.c
@@ -2,17 +2,15 @@
#include <rtdevice.h>
#include "utest.h"
-#define SERIAL_UART_NAME "uart2"
-
#ifdef UTEST_SERIAL_TC
static rt_bool_t nonblock_read(rt_device_t uart_dev)
{
rt_size_t total_length, recv_length;
- rt_uint8_t uart_read_buffer[1024], log_buffer[64];
+ char uart_read_buffer[1024], log_buffer[64];
/* make sure device is closed and reopen it */
- while(rt_device_close(uart_dev) != -RT_ERROR);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING);
rt_sprintf(log_buffer, "\nNONBLOCKING READ BEGIN, PLEASE SEND SOME DATAS\n");
@@ -22,9 +20,8 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev)
rt_device_write(uart_dev, 0, "5\n", 2);
recv_length = 0;
recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
- rt_device_write(uart_dev, 0, uart_read_buffer, 256);
+ rt_device_write(uart_dev, 0, uart_read_buffer, 256);
total_length += recv_length;
- rt_thread_mdelay(1000);
rt_sprintf(log_buffer, "\nnonblock : %d bytes read, total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
@@ -34,29 +31,26 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev)
recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
rt_device_write(uart_dev, 0, uart_read_buffer, 256);
total_length += recv_length;
- rt_thread_mdelay(1000);
- rt_sprintf(log_buffer,"\nnonblock : %d bytes read , total: %d \n", recv_length, total_length);
- rt_device_write(uart_dev,0,log_buffer, rt_strlen(log_buffer));
+ rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length);
+ rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
rt_device_write(uart_dev, 0, "3\n", 2);
recv_length = 0;
recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 256);
rt_device_write(uart_dev, 0, uart_read_buffer, 256);
total_length += recv_length;
- rt_thread_mdelay(1000);
rt_sprintf(log_buffer, "\nnonblock : %d bytes read, total: %d \n", recv_length, total_length);
- rt_device_write(uart_dev,0,log_buffer, rt_strlen(log_buffer));
+ rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
rt_device_write(uart_dev, 0, "2\n", 2);
recv_length = 0;
recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128);
rt_device_write(uart_dev, 0, uart_read_buffer, 128);
total_length += recv_length;
- rt_thread_mdelay(1000);
- rt_sprintf(log_buffer,"\nnonblock : %d bytes read , total: %d \n", recv_length, total_length);
+ rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
rt_device_write(uart_dev, 0, "1\n", 2);
@@ -64,7 +58,6 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev)
recv_length = rt_device_read(uart_dev, -1, uart_read_buffer, 128);
rt_device_write(uart_dev, 0, uart_read_buffer, 128);
total_length += recv_length;
- rt_thread_mdelay(1000);
rt_sprintf(log_buffer, "\nnonblock : %d bytes read , total: %d \n", recv_length, total_length);
rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));
@@ -78,10 +71,10 @@ static rt_bool_t nonblock_read(rt_device_t uart_dev)
static void uart_test_nonblocking_rx(void)
{
rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
+ uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
uassert_not_null(uart_dev);
- uassert_true (nonblock_read(uart_dev));
+ uassert_true(nonblock_read(uart_dev));
}
static rt_err_t utest_tc_init(void)
@@ -91,10 +84,8 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
- while(rt_device_close(uart_dev) != -RT_ERROR);
- rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c
index eb88abceb4..7723ef56b1 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c
@@ -2,92 +2,90 @@
#include <rtdevice.h>
#include "utest.h"
-#define SERIAL_UART_NAME "uart2"
-#define UART_SEND_TIMES 400
+#define UART_SEND_TIMES 100
#define UART_TEST_NUMBER 6
+
#ifdef UTEST_SERIAL_TC
static rt_bool_t nonblock_write(rt_device_t uart_dev)
{
- rt_size_t wr_sz = 0, tmp = 0, i, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER], index;
- rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER];
+ rt_size_t wr_sz = 0, tmp = 0, i, write_num_array[UART_TEST_NUMBER], total_write_num[UART_TEST_NUMBER], index;
+ rt_tick_t tick1, tick2, tick_array[UART_TEST_NUMBER];
rt_uint8_t uart_write_buffer[1024];
for (i = 0; i < 1024; i++)
uart_write_buffer[i] = '0' + (i % 50);
/* make sure device is closed and reopen it */
- while(rt_device_close(uart_dev) != -RT_ERROR);
- uart_dev = rt_device_find(SERIAL_UART_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_NON_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING);
LOG_D("\nNONBLOCKING WRITE BEGIN\n");
- rt_thread_mdelay(2000);
index = 0;
- tmp = 0;
+ tmp = 0;
tick1 = rt_tick_get();
for (i = 0; i < UART_SEND_TIMES; i++)
{
wr_sz = 0;
- while(wr_sz < 1024)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024-wr_sz);
+ while (wr_sz < 1024)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024 - wr_sz);
tmp += wr_sz;
}
- tick2 = rt_tick_get();
- total_write_num[index] = UART_SEND_TIMES * 1024;
- tick_array[index] = tick2 - tick1;
+ tick2 = rt_tick_get();
+ total_write_num[index] = UART_SEND_TIMES * 1024;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = tmp;
wr_sz = 0;
tick1 = rt_tick_get();
- while(wr_sz < 8)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 8-wr_sz);
- tick2 = rt_tick_get();
- total_write_num[index] = 8;
- tick_array[index] = tick2 - tick1;
+ while (wr_sz < 8)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 8 - wr_sz);
+ tick2 = rt_tick_get();
+ total_write_num[index] = 8;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
wr_sz = 0;
tick1 = rt_tick_get();
- while(wr_sz < 32)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 32-wr_sz);
- tick2 = rt_tick_get();
- total_write_num[index] = 32;
- tick_array[index] = tick2 - tick1;
+ while (wr_sz < 32)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 32 - wr_sz);
+ tick2 = rt_tick_get();
+ total_write_num[index] = 32;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
wr_sz = 0;
tick1 = rt_tick_get();
- while(wr_sz < 128)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 128-wr_sz);
- tick2 = rt_tick_get();
- total_write_num[index] = 128;
- tick_array[index] = tick2 - tick1;
+ while (wr_sz < 128)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 128 - wr_sz);
+ tick2 = rt_tick_get();
+ total_write_num[index] = 128;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
wr_sz = 0;
tick1 = rt_tick_get();
- while(wr_sz < 512)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 512-wr_sz);
- tick2 = rt_tick_get();
- total_write_num[index] = 512;
- tick_array[index] = tick2 - tick1;
+ while (wr_sz < 512)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 512 - wr_sz);
+ tick2 = rt_tick_get();
+ total_write_num[index] = 512;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
wr_sz = 0;
tick1 = rt_tick_get();
- while(wr_sz < 1024)
- wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024-wr_sz);
- tick2 = rt_tick_get();
- total_write_num[index] = 1024;
- tick_array[index] = tick2 - tick1;
+ while (wr_sz < 1024)
+ wr_sz += rt_device_write(uart_dev, 0, &uart_write_buffer[wr_sz], 1024 - wr_sz);
+ tick2 = rt_tick_get();
+ total_write_num[index] = 1024;
+ tick_array[index] = tick2 - tick1;
write_num_array[index++] = wr_sz;
- rt_thread_mdelay(1000);
LOG_D("\nNONBLOCKING_TX END\n");
- for(i = 0; i < index; i++)
+ for (i = 0; i < index; i++)
{
LOG_D("\nNONBLOCKING_MODE : write %d / %d bytes in %d ticks\n", write_num_array[i], total_write_num[i], tick_array[i]);
rt_thread_mdelay(1000);
@@ -99,10 +97,10 @@ static rt_bool_t nonblock_write(rt_device_t uart_dev)
static void uart_test_nonblocking_tx(void)
{
rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
+ uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
uassert_not_null(uart_dev);
- uassert_true (nonblock_write(uart_dev));
+ uassert_true(nonblock_write(uart_dev));
}
static rt_err_t utest_tc_init(void)
@@ -112,10 +110,8 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- rt_device_t uart_dev;
- uart_dev = rt_device_find(SERIAL_UART_NAME);
- while(rt_device_close(uart_dev) != -RT_ERROR);
- rt_device_open(uart_dev, RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c
new file mode 100644
index 0000000000..912d1ecd7c
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+static rt_uint8_t uart_over_flag = RT_FALSE;
+static rt_bool_t uart_result = RT_TRUE;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+
+static void uart_send_entry(void *parameter)
+{
+ rt_uint32_t send_len;
+ rt_uint8_t *uart_write_buffer = RT_NULL;
+ rt_uint32_t i = 0;
+ send_len = *(rt_uint32_t *)parameter;
+
+ /* assign send buffer */
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
+ if (uart_write_buffer == RT_NULL)
+ {
+ LOG_E("Without spare memory for uart dma!");
+ uart_result = RT_FALSE;
+ return;
+ }
+
+ rt_memset(uart_write_buffer, 0, send_len);
+
+ for (i = 0; i < send_len; i++)
+ {
+ uart_write_buffer[i] = (rt_uint8_t)i;
+ }
+ /* send buffer */
+ if (rt_device_write(&serial->parent, 0, uart_write_buffer, send_len) != send_len)
+ {
+ LOG_E("device write failed\r\n");
+ }
+ rt_free(uart_write_buffer);
+}
+
+static void uart_rec_entry(void *parameter)
+{
+ rt_uint32_t rev_len;
+ rt_uint8_t *uart_write_buffer;
+ rt_int32_t cnt, i;
+ rev_len = *(rt_uint32_t *)parameter;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (rev_len + 1));
+
+ while (1)
+ {
+ cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE);
+ if (cnt != RT_SERIAL_TC_RXBUF_SIZE)
+ {
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+
+#ifdef RT_SERIAL_BUF_STRATEGY_DROP
+ for (i = 0; i < cnt; i++)
+ {
+ if (uart_write_buffer[i] != i)
+ {
+ LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], i);
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+ }
+#else
+ for (i = cnt - 1; i >= 0; i--)
+ {
+ if (uart_write_buffer[i] != ((rev_len - (cnt - i)) % (UINT8_MAX + 1)))
+ {
+ LOG_E("Read Different data2 -> former data: %x, current data: %x.", uart_write_buffer[i], ((rev_len - (cnt - i)) % (UINT8_MAX + 1)));
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+ }
+#endif /* RT_SERIAL_BUF_STRATEGY_DROP */
+ break;
+ }
+ rt_free(uart_write_buffer);
+ uart_over_flag = RT_TRUE;
+}
+
+static rt_err_t uart_api(rt_uint32_t length)
+{
+ rt_thread_t thread_send = RT_NULL;
+ rt_thread_t thread_recv = RT_NULL;
+ rt_err_t result = RT_EOK;
+ uart_over_flag = RT_FALSE;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ uart_result = RT_FALSE;
+ return -RT_ERROR;
+ }
+
+ rt_int32_t timeout = 5000;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
+ thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 4, 10);
+ thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 2048, RT_THREAD_PRIORITY_MAX - 5, 10);
+ if ((thread_send != RT_NULL) && (thread_recv != RT_NULL))
+ {
+ rt_thread_startup(thread_send);
+ /* waiting for data transmission to complete*/
+ rt_thread_mdelay(length * 0.0868 + 10);
+ rt_thread_startup(thread_recv);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (uart_result != RT_TRUE)
+ {
+ LOG_E("The test for uart dma is failure.");
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ if (uart_over_flag == RT_TRUE)
+ {
+ goto __exit;
+ }
+ /* waiting for test over */
+ rt_thread_mdelay(5);
+ }
+__exit:
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result;
+}
+
+static void tc_uart_api(void)
+{
+ rt_uint32_t count = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ srand(rt_tick_get());
+ while (RT_SERIAL_TC_SEND_ITERATIONS - count)
+ {
+ num = (rand() % RT_SERIAL_TC_RXBUF_SIZE) + 1;
+ if (uart_api(num + RT_SERIAL_TC_RXBUF_SIZE) == RT_EOK)
+ LOG_I("data_lens [%3d], it is correct to read and write data. [%d] count testing.", num, ++count);
+ else
+ {
+ LOG_E("uart test error");
+ break;
+ }
+ }
+
+__exit:
+ uassert_true(uart_result == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_overflow_rxb_txb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c
index 8b2205ee1a..40702e8fb2 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -13,25 +13,20 @@
#include <rtdevice.h>
#include <stdlib.h>
-#define TC_UART_DEVICE_NAME "uart2"
-#define TC_UART_SEND_TIMES 100
-
#ifdef UTEST_SERIAL_TC
-#define TEST_UART_NAME TC_UART_DEVICE_NAME
-
static struct rt_serial_device *serial;
-static rt_uint8_t uart_over_flag;
-static rt_bool_t uart_result = RT_TRUE;
+static rt_uint8_t uart_over_flag;
+static rt_bool_t uart_result = RT_TRUE;
static rt_err_t uart_find(void)
{
- serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME);
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
if (serial == RT_NULL)
{
- LOG_E("find %s device failed!\n", TEST_UART_NAME);
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
return -RT_ERROR;
}
@@ -44,7 +39,7 @@ static void uart_send_entry(void *parameter)
rt_uint16_t send_len;
rt_uint32_t i = 0;
- send_len = *(rt_uint16_t *)parameter;
+ send_len = *(rt_uint16_t *)parameter;
/* assign send buffer */
uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
if (uart_write_buffer == RT_NULL)
@@ -66,7 +61,6 @@ static void uart_send_entry(void *parameter)
LOG_E("device write failed\r\n");
}
rt_free(uart_write_buffer);
-
}
static void uart_rec_entry(void *parameter)
@@ -74,17 +68,17 @@ static void uart_rec_entry(void *parameter)
rt_uint16_t rev_len;
rev_len = *(rt_uint16_t *)parameter;
- rt_uint8_t *ch;
- ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
- rt_int32_t cnt, i;
- rt_uint8_t last_old_data;
- rt_bool_t fisrt_flag = RT_TRUE;
+ rt_uint8_t *uart_write_buffer;
+ uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
+ rt_int32_t cnt, i;
+ rt_uint8_t last_old_data;
+ rt_bool_t fisrt_flag = RT_TRUE;
rt_uint32_t all_receive_length = 0;
while (1)
{
- cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len);
+ cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len);
if (cnt == 0)
{
continue;
@@ -92,11 +86,11 @@ static void uart_rec_entry(void *parameter)
if (fisrt_flag != RT_TRUE)
{
- if ((rt_uint8_t)(last_old_data + 1) != ch[0])
+ if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
{
- LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]);
+ LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -107,12 +101,12 @@ static void uart_rec_entry(void *parameter)
for (i = 0; i < cnt - 1; i++)
{
- if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1])
+ if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
{
- LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]);
+ LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -120,9 +114,9 @@ static void uart_rec_entry(void *parameter)
if (all_receive_length >= rev_len)
break;
else
- last_old_data = ch[cnt - 1];
+ last_old_data = uart_write_buffer[cnt - 1];
}
- rt_free(ch);
+ rt_free(uart_write_buffer);
uart_over_flag = RT_TRUE;
}
@@ -130,8 +124,8 @@ static rt_err_t uart_api(rt_uint16_t length)
{
rt_thread_t thread_send = RT_NULL;
rt_thread_t thread_recv = RT_NULL;
- rt_err_t result = RT_EOK;
- uart_over_flag = RT_FALSE;
+ rt_err_t result = RT_EOK;
+ uart_over_flag = RT_FALSE;
result = uart_find();
if (result != RT_EOK)
@@ -141,13 +135,16 @@ static rt_err_t uart_api(rt_uint16_t length)
/* Reinitialize */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
- config.baud_rate = BAUD_RATE_115200;
- config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
- config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
-
if (result != RT_EOK)
{
LOG_E("Open uart device failed.");
@@ -155,6 +152,9 @@ static rt_err_t uart_api(rt_uint16_t length)
return -RT_ERROR;
}
+ rt_int32_t timeout = 5000;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
thread_send = rt_thread_create("uart_send", uart_send_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 4, 10);
thread_recv = rt_thread_create("uart_recv", uart_rec_entry, &length, 1024, RT_THREAD_PRIORITY_MAX - 5, 10);
if ((thread_send != RT_NULL) && (thread_recv != RT_NULL))
@@ -183,27 +183,56 @@ static rt_err_t uart_api(rt_uint16_t length)
/* waiting for test over */
rt_thread_mdelay(5);
}
+
__exit:
rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ uart_over_flag = RT_FALSE;
return result;
}
static void tc_uart_api(void)
{
- rt_uint32_t times = 0;
- rt_uint16_t num = 0;
- while (TC_UART_SEND_TIMES - times)
+ rt_uint32_t count = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ srand(rt_tick_get());
+ while (RT_SERIAL_TC_SEND_ITERATIONS - count)
{
num = (rand() % 1000) + 1;
- if(uart_api(num) == RT_EOK)
- LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times);
+ if (uart_api(num) == RT_EOK)
+ LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count);
else
{
LOG_E("uart test error");
break;
}
}
- uassert_true(uart_over_flag == RT_TRUE);
+
+__exit:
+ uassert_true(uart_result == RT_TRUE);
}
static rt_err_t utest_tc_init(void)
@@ -214,9 +243,10 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- uart_result = RT_TRUE;
- uart_over_flag = RT_FALSE;
-
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c
index f03a24fe13..c2e6be8205 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -13,26 +13,21 @@
#include <rtdevice.h>
#include <stdlib.h>
-#define TC_UART_DEVICE_NAME "uart2"
-#define TC_UART_SEND_TIMES 100
-
#ifdef UTEST_SERIAL_TC
-#define TEST_UART_NAME TC_UART_DEVICE_NAME
-
static struct rt_serial_device *serial;
-static rt_sem_t tx_sem;
-static rt_uint8_t uart_over_flag;
-static rt_bool_t uart_result = RT_TRUE;
+static rt_sem_t tx_sem;
+static rt_uint8_t uart_over_flag;
+static rt_bool_t uart_result = RT_TRUE;
static rt_err_t uart_find(void)
{
- serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME);
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
if (serial == RT_NULL)
{
- LOG_E("find %s device failed!\n", TEST_UART_NAME);
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
return -RT_ERROR;
}
@@ -50,10 +45,10 @@ static void uart_send_entry(void *parameter)
{
rt_uint8_t *uart_write_buffer;
rt_uint16_t send_len, len = 0;
- rt_err_t result;
+ rt_err_t result;
rt_uint32_t i = 0;
- send_len = *(rt_uint16_t *)parameter;
+ send_len = *(rt_uint16_t *)parameter;
/* assign send buffer */
uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
if (uart_write_buffer == RT_NULL)
@@ -72,15 +67,14 @@ static void uart_send_entry(void *parameter)
/* send buffer */
while (send_len - len)
{
- len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
- result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
+ len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
+ result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
LOG_E("take sem err in send.");
}
}
rt_free(uart_write_buffer);
-
}
static void uart_rec_entry(void *parameter)
@@ -88,16 +82,16 @@ static void uart_rec_entry(void *parameter)
rt_uint16_t rev_len;
rev_len = *(rt_uint16_t *)parameter;
- rt_uint8_t *ch;
- ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
- rt_int32_t cnt, i;
- rt_uint8_t last_old_data;
- rt_bool_t fisrt_flag = RT_TRUE;
+ rt_uint8_t *uart_write_buffer;
+ uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
+ rt_int32_t cnt, i;
+ rt_uint8_t last_old_data;
+ rt_bool_t fisrt_flag = RT_TRUE;
rt_uint32_t all_receive_length = 0;
while (1)
{
- cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len);
+ cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len);
if (cnt != rev_len)
{
continue;
@@ -105,11 +99,11 @@ static void uart_rec_entry(void *parameter)
if (fisrt_flag != RT_TRUE)
{
- if ((rt_uint8_t)(last_old_data + 1) != ch[0])
+ if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
{
- LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]);
+ LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -120,12 +114,12 @@ static void uart_rec_entry(void *parameter)
for (i = 0; i < cnt - 1; i++)
{
- if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1])
+ if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
{
- LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]);
+ LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -133,9 +127,9 @@ static void uart_rec_entry(void *parameter)
if (all_receive_length >= rev_len)
break;
else
- last_old_data = ch[cnt - 1];
+ last_old_data = uart_write_buffer[cnt - 1];
}
- rt_free(ch);
+ rt_free(uart_write_buffer);
uart_over_flag = RT_TRUE;
}
@@ -143,8 +137,8 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
{
rt_thread_t thread_send = RT_NULL;
rt_thread_t thread_recv = RT_NULL;
- rt_err_t result = RT_EOK;
- uart_over_flag = RT_FALSE;
+ rt_err_t result = RT_EOK;
+ uart_over_flag = RT_FALSE;
result = uart_find();
if (result != RT_EOK)
@@ -162,13 +156,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
/* Reinitialize */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
- config.baud_rate = BAUD_RATE_115200;
- config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
- config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);
-
if (result != RT_EOK)
{
LOG_E("Open uart device failed.");
@@ -176,6 +173,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
return -RT_ERROR;
}
+ rt_int32_t timeout = 5000;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
/* set receive callback function */
result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion);
if (result != RT_EOK)
@@ -217,25 +217,53 @@ __exit:
rt_sem_delete(tx_sem);
rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ uart_over_flag = RT_FALSE;
return result;
}
static void tc_uart_api(void)
{
- rt_uint32_t times = 0;
- rt_uint16_t num = 0;
- while (TC_UART_SEND_TIMES - times)
+ rt_uint32_t count = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ srand(rt_tick_get());
+ while (RT_SERIAL_TC_SEND_ITERATIONS - count)
{
num = (rand() % 1000) + 1;
- if(uart_api(num) == RT_EOK)
- LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times);
+ if (uart_api(num) == RT_EOK)
+ LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count);
else
{
LOG_E("uart test error");
break;
}
}
- uassert_true(uart_over_flag == RT_TRUE);
+
+__exit:
+ uassert_true(uart_result == RT_TRUE);
}
static rt_err_t utest_tc_init(void)
@@ -246,10 +274,11 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- tx_sem = RT_NULL;
- uart_result = RT_TRUE;
- uart_over_flag = RT_FALSE;
-
+ tx_sem = RT_NULL;
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c
index c1c88ddc9f..a1efcc7315 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -13,26 +13,21 @@
#include <rtdevice.h>
#include <stdlib.h>
-#define TC_UART_DEVICE_NAME "uart2"
-#define TC_UART_SEND_TIMES 100
-
#ifdef UTEST_SERIAL_TC
-#define TEST_UART_NAME TC_UART_DEVICE_NAME
-
static struct rt_serial_device *serial;
-static rt_sem_t rx_sem;
-static rt_uint8_t uart_over_flag;
-static rt_bool_t uart_result = RT_TRUE;
+static rt_sem_t rx_sem;
+static rt_uint8_t uart_over_flag;
+static rt_bool_t uart_result = RT_TRUE;
static rt_err_t uart_find(void)
{
- serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME);
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
if (serial == RT_NULL)
{
- LOG_E("find %s device failed!\n", TEST_UART_NAME);
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
return -RT_ERROR;
}
@@ -52,7 +47,7 @@ static void uart_send_entry(void *parameter)
rt_uint16_t send_len;
rt_uint32_t i = 0;
- send_len = *(rt_uint16_t *)parameter;
+ send_len = *(rt_uint16_t *)parameter;
/* assign send buffer */
uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
@@ -83,11 +78,11 @@ static void uart_rec_entry(void *parameter)
rt_uint16_t rev_len;
rev_len = *(rt_uint16_t *)parameter;
- rt_uint8_t *ch;
- ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
- rt_int32_t cnt, i;
- rt_uint8_t last_old_data;
- rt_bool_t fisrt_flag = RT_TRUE;
+ rt_uint8_t *uart_write_buffer;
+ uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
+ rt_int32_t cnt, i;
+ rt_uint8_t last_old_data;
+ rt_bool_t fisrt_flag = RT_TRUE;
rt_uint32_t all_receive_length = 0;
while (1)
@@ -100,7 +95,7 @@ static void uart_rec_entry(void *parameter)
LOG_E("take sem err in recv.");
}
- cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len);
+ cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len);
if (cnt == 0)
{
continue;
@@ -108,11 +103,11 @@ static void uart_rec_entry(void *parameter)
if (fisrt_flag != RT_TRUE)
{
- if ((rt_uint8_t)(last_old_data + 1) != ch[0])
+ if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
{
- LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]);
+ LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -123,12 +118,12 @@ static void uart_rec_entry(void *parameter)
for (i = 0; i < cnt - 1; i++)
{
- if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1])
+ if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
{
- LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]);
+ LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -136,9 +131,9 @@ static void uart_rec_entry(void *parameter)
if (all_receive_length >= rev_len)
break;
else
- last_old_data = ch[cnt - 1];
+ last_old_data = uart_write_buffer[cnt - 1];
}
- rt_free(ch);
+ rt_free(uart_write_buffer);
uart_over_flag = RT_TRUE;
}
@@ -146,7 +141,7 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
{
rt_thread_t thread_send = RT_NULL;
rt_thread_t thread_recv = RT_NULL;
- rt_err_t result = RT_EOK;
+ rt_err_t result = RT_EOK;
result = uart_find();
if (result != RT_EOK)
@@ -164,13 +159,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
/* reinitialize */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
- config.baud_rate = BAUD_RATE_115200;
- config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
- config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
-
if (result != RT_EOK)
{
LOG_E("Open uart device failed.");
@@ -179,6 +177,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
return -RT_ERROR;
}
+ rt_int32_t timeout = 5000;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
/* set receive callback function */
result = rt_device_set_rx_indicate(&serial->parent, uart_rx_indicate);
if (result != RT_EOK)
@@ -219,25 +220,52 @@ __exit:
if (rx_sem)
rt_sem_delete(rx_sem);
rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
uart_over_flag = RT_FALSE;
return result;
}
static void tc_uart_api(void)
{
- rt_uint32_t times = 0;
- rt_uint16_t num = 0;
- while (TC_UART_SEND_TIMES - times)
+ rt_uint32_t count = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ srand(rt_tick_get());
+ while (RT_SERIAL_TC_SEND_ITERATIONS - count)
{
num = (rand() % 1000) + 1;
- if(uart_api(num) == RT_EOK)
- LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times);
+ if (uart_api(num) == RT_EOK)
+ LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count);
else
{
LOG_E("uart test error");
break;
}
}
+
+__exit:
uassert_true(uart_result == RT_TRUE);
}
@@ -249,10 +277,11 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- rx_sem = RT_NULL;
- uart_result = RT_TRUE;
- uart_over_flag = RT_FALSE;
-
+ rx_sem = RT_NULL;
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c
index ad8d20b8cf..edc66e2be8 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c
+++ b/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -13,27 +13,22 @@
#include <rtdevice.h>
#include <stdlib.h>
-#define TC_UART_DEVICE_NAME "uart2"
-#define TC_UART_SEND_TIMES 100
-
#ifdef UTEST_SERIAL_TC
-#define TEST_UART_NAME TC_UART_DEVICE_NAME
-
static struct rt_serial_device *serial;
-static rt_sem_t tx_sem;
-static rt_sem_t rx_sem;
-static rt_uint8_t uart_over_flag;
-static rt_bool_t uart_result = RT_TRUE;
+static rt_sem_t tx_sem;
+static rt_sem_t rx_sem;
+static rt_uint8_t uart_over_flag;
+static rt_bool_t uart_result = RT_TRUE;
static rt_err_t uart_find(void)
{
- serial = (struct rt_serial_device *)rt_device_find(TEST_UART_NAME);
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
if (serial == RT_NULL)
{
- LOG_E("find %s device failed!\n", TEST_UART_NAME);
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
return -RT_ERROR;
}
@@ -56,10 +51,10 @@ static void uart_send_entry(void *parameter)
{
rt_uint8_t *uart_write_buffer;
rt_uint16_t send_len, len = 0;
- rt_err_t result;
+ rt_err_t result;
rt_uint32_t i = 0;
- send_len = *(rt_uint16_t *)parameter;
+ send_len = *(rt_uint16_t *)parameter;
/* assign send buffer */
uart_write_buffer = (rt_uint8_t *)rt_malloc(send_len);
if (uart_write_buffer == RT_NULL)
@@ -78,15 +73,14 @@ static void uart_send_entry(void *parameter)
/* send buffer */
while (send_len - len)
{
- len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
- result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
+ len += rt_device_write(&serial->parent, 0, uart_write_buffer + len, send_len - len);
+ result = rt_sem_take(tx_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
LOG_E("take sem err in send.");
}
}
rt_free(uart_write_buffer);
-
}
static void uart_rec_entry(void *parameter)
@@ -94,11 +88,11 @@ static void uart_rec_entry(void *parameter)
rt_uint16_t rev_len;
rev_len = *(rt_uint16_t *)parameter;
- rt_uint8_t *ch;
- ch = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
- rt_int32_t cnt, i;
- rt_uint8_t last_old_data;
- rt_bool_t fisrt_flag = RT_TRUE;
+ rt_uint8_t *uart_write_buffer;
+ uart_write_buffer = (rt_uint8_t *)rt_calloc(1, sizeof(rt_uint8_t) * (rev_len + 1));
+ rt_int32_t cnt, i;
+ rt_uint8_t last_old_data;
+ rt_bool_t fisrt_flag = RT_TRUE;
rt_uint32_t all_receive_length = 0;
while (1)
@@ -111,7 +105,7 @@ static void uart_rec_entry(void *parameter)
LOG_E("take sem err in recv.");
}
- cnt = rt_device_read(&serial->parent, 0, (void *)ch, rev_len);
+ cnt = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, rev_len);
if (cnt == 0)
{
continue;
@@ -119,11 +113,11 @@ static void uart_rec_entry(void *parameter)
if (fisrt_flag != RT_TRUE)
{
- if ((rt_uint8_t)(last_old_data + 1) != ch[0])
+ if ((rt_uint8_t)(last_old_data + 1) != uart_write_buffer[0])
{
- LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, ch[0]);
+ LOG_E("_Read Different data -> former data: %x, current data: %x.", last_old_data, uart_write_buffer[0]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -134,12 +128,12 @@ static void uart_rec_entry(void *parameter)
for (i = 0; i < cnt - 1; i++)
{
- if ((rt_uint8_t)(ch[i] + 1) != ch[i + 1])
+ if ((rt_uint8_t)(uart_write_buffer[i] + 1) != uart_write_buffer[i + 1])
{
- LOG_E("Read Different data -> former data: %x, current data: %x.", ch[i], ch[i + 1]);
+ LOG_E("Read Different data -> former data: %x, current data: %x.", uart_write_buffer[i], uart_write_buffer[i + 1]);
uart_result = RT_FALSE;
- rt_free(ch);
+ rt_free(uart_write_buffer);
return;
}
}
@@ -147,9 +141,9 @@ static void uart_rec_entry(void *parameter)
if (all_receive_length >= rev_len)
break;
else
- last_old_data = ch[cnt - 1];
+ last_old_data = uart_write_buffer[cnt - 1];
}
- rt_free(ch);
+ rt_free(uart_write_buffer);
uart_over_flag = RT_TRUE;
}
@@ -157,8 +151,8 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
{
rt_thread_t thread_send = RT_NULL;
rt_thread_t thread_recv = RT_NULL;
- rt_err_t result = RT_EOK;
- uart_over_flag = RT_FALSE;
+ rt_err_t result = RT_EOK;
+ uart_over_flag = RT_FALSE;
result = uart_find();
if (result != RT_EOK)
@@ -184,13 +178,16 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
/* reinitialize */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
- config.baud_rate = BAUD_RATE_115200;
- config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
- config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING);
-
if (result != RT_EOK)
{
LOG_E("Open uart device failed.");
@@ -198,6 +195,9 @@ static rt_err_t uart_api(rt_uint16_t test_buf)
return -RT_ERROR;
}
+ rt_int32_t timeout = 5000;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
/* set receive callback function */
result = rt_device_set_tx_complete(&serial->parent, uart_tx_completion);
if (result != RT_EOK)
@@ -248,25 +248,53 @@ __exit:
rt_sem_delete(rx_sem);
rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ uart_over_flag = RT_FALSE;
return result;
}
static void tc_uart_api(void)
{
- rt_uint32_t times = 0;
- rt_uint16_t num = 0;
- while (TC_UART_SEND_TIMES - times)
+ rt_uint32_t count = 0;
+ rt_uint16_t num = 0;
+ rt_uint32_t i = 0;
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_TXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ for (i = 1; i < 10; i++)
+ {
+ if (uart_api(RT_SERIAL_TC_RXBUF_SIZE * i + i % 2) == RT_EOK)
+ 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);
+ else
+ {
+ LOG_E("uart test error");
+ goto __exit;
+ }
+ }
+
+ srand(rt_tick_get());
+ while (RT_SERIAL_TC_SEND_ITERATIONS - count)
{
num = (rand() % 1000) + 1;
- if(uart_api(num) == RT_EOK)
- LOG_I("data_lens [%3d], it is correct to read and write data. [%d] times testing.", num, ++times);
+ if (uart_api(num) == RT_EOK)
+ LOG_I("data_lens [%4d], it is correct to read and write data. [%d] count testing.", num, ++count);
else
{
LOG_E("uart test error");
break;
}
}
- uassert_true(uart_over_flag == RT_TRUE);
+
+__exit:
+ uassert_true(uart_result == RT_TRUE);
}
static rt_err_t utest_tc_init(void)
@@ -277,10 +305,11 @@ static rt_err_t utest_tc_init(void)
static rt_err_t utest_tc_cleanup(void)
{
- tx_sem = RT_NULL;
- uart_result = RT_TRUE;
- uart_over_flag = RT_FALSE;
-
+ tx_sem = RT_NULL;
+ uart_result = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
return RT_EOK;
}
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c
new file mode 100644
index 0000000000..ae42ee5d05
--- /dev/null
+++ b/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ *
+ */
+
+#include <rtthread.h>
+#include "utest.h"
+#include <rtdevice.h>
+#include <stdlib.h>
+
+/* */
+
+#ifdef UTEST_SERIAL_TC
+
+static struct rt_serial_device *serial;
+static rt_bool_t uart_result = RT_TRUE;
+static rt_uint8_t uart_write_flag = RT_TRUE;
+static rt_uint8_t uart_over_flag = RT_FALSE;
+
+static rt_err_t uart_find(void)
+{
+ serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+
+ if (serial == RT_NULL)
+ {
+ LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+
+static void uart_send_entry(void *parameter)
+{
+ rt_uint8_t *uart_write_buffer = RT_NULL;
+ rt_uint32_t i = 0;
+
+ /* assign send buffer */
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE);
+ if (uart_write_buffer == RT_NULL)
+ {
+ LOG_E("Without spare memory for uart dma!");
+ uart_result = RT_FALSE;
+ return;
+ }
+
+ for (i = 0; i < RT_SERIAL_TC_RXBUF_SIZE; i++)
+ {
+ uart_write_buffer[i] = (rt_uint8_t)i;
+ }
+
+ while (1)
+ {
+ if (uart_write_flag == RT_FALSE)
+ break;
+
+ rt_device_write(&serial->parent, 0, uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE / 3);
+ rt_thread_mdelay(40);
+ }
+
+ rt_free(uart_write_buffer);
+}
+
+static void uart_rec_entry(void *parameter)
+{
+ rt_uint8_t *uart_write_buffer;
+ rt_tick_t old_tick;
+ rt_tick_t tick_diff;
+ rt_ssize_t recv_len;
+ rt_uint32_t i;
+ rt_int32_t timeout = 0;
+ uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * (RT_SERIAL_TC_RXBUF_SIZE * 10 + 1));
+
+ timeout = 100;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);
+
+ uart_write_flag = RT_TRUE;
+ for (i = 0; i < 10; i++)
+ {
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
+ old_tick = rt_tick_get();
+ recv_len = rt_device_read(&serial->parent, 0, (void *)uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE);
+ tick_diff = rt_tick_get() - old_tick;
+ if (tick_diff > 100 + 1 || tick_diff < 100)
+ {
+ LOG_E("timeout_test: recv_size [%d], RX block time [%d], expect_time [100 - 101]", recv_len, tick_diff);
+ uart_write_flag = RT_FALSE;
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ rt_thread_mdelay(60);
+ return;
+ }
+
+ LOG_I("timeout_test: RX block time [%d], expect_time [100 - 101]", tick_diff);
+ }
+ uart_write_flag = RT_FALSE;
+
+ rt_thread_mdelay(60);
+ timeout = 10;
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&timeout);
+
+ for (i = 0; i < 10; i++)
+ {
+ old_tick = rt_tick_get();
+ recv_len = rt_device_write(&serial->parent, 0, uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE * 10);
+ tick_diff = rt_tick_get() - old_tick;
+ if (tick_diff > 10 + 1 || tick_diff < 10)
+ {
+ LOG_E("timeout_test: recv_size [%d], TX block time [%d], expect_time [10 - 11]", recv_len, tick_diff);
+ uart_result = RT_FALSE;
+ rt_free(uart_write_buffer);
+ return;
+ }
+
+ LOG_I("timeout_test: TX block time [%d], expect_time [10 - 11]", tick_diff);
+ rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
+ }
+
+ rt_free(uart_write_buffer);
+ uart_over_flag = RT_TRUE;
+}
+
+static rt_bool_t uart_api()
+{
+ rt_thread_t thread_send = RT_NULL;
+ rt_thread_t thread_recv = RT_NULL;
+ rt_err_t result = RT_EOK;
+
+ result = uart_find();
+ if (result != RT_EOK)
+ {
+ return RT_FALSE;
+ }
+
+ /* Reinitialize */
+ struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+ config.baud_rate = BAUD_RATE_115200;
+ config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
+ config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
+#ifdef RT_SERIAL_USING_DMA
+ config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
+#endif
+ rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
+
+ result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
+ if (result != RT_EOK)
+ {
+ LOG_E("Open uart device failed.");
+ return RT_FALSE;
+ }
+
+ thread_send = rt_thread_create("uart_send", uart_send_entry, NULL, 2048, RT_THREAD_PRIORITY_MAX - 4, 10);
+ thread_recv = rt_thread_create("uart_recv", uart_rec_entry, NULL, 2048, RT_THREAD_PRIORITY_MAX - 5, 10);
+
+ if ((thread_send != RT_NULL) && (thread_recv != RT_NULL))
+ {
+ rt_thread_startup(thread_send);
+ rt_thread_startup(thread_recv);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (uart_result != RT_TRUE)
+ {
+ LOG_E("The test for uart dma is failure.");
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ if (uart_over_flag == RT_TRUE)
+ {
+ goto __exit;
+ }
+ /* waiting for test over */
+ rt_thread_mdelay(5);
+ }
+
+__exit:
+ rt_device_close(&serial->parent);
+ rt_thread_mdelay(5);
+ return result == RT_EOK ? RT_TRUE : RT_FALSE;
+}
+
+static void tc_uart_api(void)
+{
+ uassert_true(uart_api() == RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+ uart_result = RT_TRUE;
+ uart_write_flag = RT_TRUE;
+ uart_over_flag = RT_FALSE;
+ rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
+ while (rt_device_close(uart_dev) != -RT_ERROR);
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(tc_uart_api);
+}
+
+UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_timeout_rxb_txb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */