diff options
| author | ryancw <[email protected]> | 2024-09-04 10:39:10 +0800 |
|---|---|---|
| committer | Rbb666 <[email protected]> | 2025-05-16 09:42:11 +0800 |
| commit | ac8fba0129f98b5c6a7c6caaa55538a53b370db2 (patch) | |
| tree | ff4cfe35207900dba802b879da2f244a3adf5f5b /examples | |
| parent | bf96f99d6bc3dfa3c7c9230d1b8e4415c02f19f0 (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')
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 */ |
