Forráskód Böngészése

[component][drivers][serial_v2] 优化serial_v2 (#10603)

* [bsp][stm32][drv_usart_v2] uart_isr不再使用链式调用,RXNE内循环读空,一些细节优化

* [componnents][drivers][serial_v2] 增加获取config接口,使用rt_tick_get_delta替代内部的时间绕回判断,写满丢弃策略rx接收数据错乱修复,clang-tidy和cppcheck审查优化

* [utest][drivers][serial_v2] 测试例程进行优化

* [bsp][stm32][drv_usart_v2] 撤回DMAMUX1修改

* [componnents][drivers][serial_v2] read和write不再返回-RT_ETIMEOUT改为已发送或读取的字节数,细节优化

* [utest][drivers][serial_v2] 增加单独的timeout测试,减少测试中的硬延时

* [utest][drivers][serial_v2] 漏提交的posix下标志位

* [utest][drivers][serial_v2] 优化测试例程

* [bsp][stm32][drv_usart_v2] transmit返回错误值,RXNE增加超时逻辑

* [componnents][drivers][serial_v2] 增加transmit错误处理,增加超时退出机制显式的避免死循环

* [componnents][drivers][serial_v2] 适配serial_v2和posix非libc标准库下的console和shell
RyanCW 4 hete
szülő
commit
e0243e87c0

+ 212 - 222
bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c

@@ -14,23 +14,21 @@
 #ifdef RT_USING_SERIAL_V2
 
 // #define DRV_DEBUG
-#define DBG_TAG              "drv.usart"
+#define DBG_TAG "drv.usart"
 #ifdef DRV_DEBUG
-#define DBG_LVL               DBG_LOG
+#define DBG_LVL DBG_LOG
 #else
-#define DBG_LVL               DBG_INFO
+#define DBG_LVL DBG_INFO
 #endif /* DRV_DEBUG */
 #include <rtdbg.h>
 
-#if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \
-    !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && \
-    !defined(BSP_USING_UART7) && !defined(BSP_USING_UART8) && !defined(BSP_USING_LPUART1)
-    #error "Please define at least one BSP_USING_UARTx"
-    /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
+#if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && !defined(BSP_USING_UART7) && !defined(BSP_USING_UART8) && !defined(BSP_USING_LPUART1)
+#error "Please define at least one BSP_USING_UARTx"
+/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
 #endif
 
 #ifdef RT_SERIAL_USING_DMA
-    static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
+static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag);
 #endif
 
 enum
@@ -73,41 +71,41 @@ enum
 };
 
 static struct stm32_uart_config uart_config[] =
-{
+    {
 #ifdef BSP_USING_UART1
-    UART1_CONFIG,
+        UART1_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART2
-    UART2_CONFIG,
+        UART2_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART3
-    UART3_CONFIG,
+        UART3_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART4
-    UART4_CONFIG,
+        UART4_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART5
-    UART5_CONFIG,
+        UART5_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART6
-    UART6_CONFIG,
+        UART6_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART7
-    UART7_CONFIG,
+        UART7_CONFIG,
 #endif
 
 #ifdef BSP_USING_UART8
-    UART8_CONFIG,
+        UART8_CONFIG,
 #endif
 
 #ifdef BSP_USING_LPUART1
-    LPUART1_CONFIG,
+        LPUART1_CONFIG,
 #endif
 };
 
@@ -120,10 +118,10 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c
     RT_ASSERT(serial != RT_NULL);
     RT_ASSERT(cfg != RT_NULL);
 
-    uart = rt_container_of(serial, struct stm32_uart, serial);
-    uart->handle.Instance          = uart->config->Instance;
-    uart->handle.Init.BaudRate     = cfg->baud_rate;
-    uart->handle.Init.Mode         = UART_MODE_TX_RX;
+    uart                       = rt_container_of(serial, struct stm32_uart, serial);
+    uart->handle.Instance      = uart->config->Instance;
+    uart->handle.Init.BaudRate = cfg->baud_rate;
+    uart->handle.Init.Mode     = UART_MODE_TX_RX;
 #ifdef USART_CR1_OVER8
     uart->handle.Init.OverSampling = cfg->baud_rate > 5000000 ? UART_OVERSAMPLING_8 : UART_OVERSAMPLING_16;
 #else
@@ -149,43 +147,43 @@ static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_c
     switch (cfg->stop_bits)
     {
     case STOP_BITS_1:
-        uart->handle.Init.StopBits   = UART_STOPBITS_1;
+        uart->handle.Init.StopBits = UART_STOPBITS_1;
         break;
     case STOP_BITS_2:
-        uart->handle.Init.StopBits   = UART_STOPBITS_2;
+        uart->handle.Init.StopBits = UART_STOPBITS_2;
         break;
     default:
-        uart->handle.Init.StopBits   = UART_STOPBITS_1;
+        uart->handle.Init.StopBits = UART_STOPBITS_1;
         break;
     }
 
     switch (cfg->parity)
     {
     case PARITY_NONE:
-        uart->handle.Init.Parity     = UART_PARITY_NONE;
+        uart->handle.Init.Parity = UART_PARITY_NONE;
         break;
     case PARITY_ODD:
-        uart->handle.Init.Parity     = UART_PARITY_ODD;
+        uart->handle.Init.Parity = UART_PARITY_ODD;
         break;
     case PARITY_EVEN:
-        uart->handle.Init.Parity     = UART_PARITY_EVEN;
+        uart->handle.Init.Parity = UART_PARITY_EVEN;
         break;
     default:
-        uart->handle.Init.Parity     = UART_PARITY_NONE;
+        uart->handle.Init.Parity = UART_PARITY_NONE;
         break;
     }
 
     switch (cfg->flowcontrol)
     {
-        case RT_SERIAL_FLOWCONTROL_NONE:
-            uart->handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-            break;
-        case RT_SERIAL_FLOWCONTROL_CTSRTS:
-            uart->handle.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
-            break;
-        default:
-            uart->handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-            break;
+    case RT_SERIAL_FLOWCONTROL_NONE:
+        uart->handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+        break;
+    case RT_SERIAL_FLOWCONTROL_CTSRTS:
+        uart->handle.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
+        break;
+    default:
+        uart->handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+        break;
     }
 
 #ifdef RT_SERIAL_USING_DMA
@@ -209,14 +207,14 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
     RT_ASSERT(serial != RT_NULL);
     uart = rt_container_of(serial, struct stm32_uart, serial);
 
-    if(ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING))
+    if (ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING))
     {
         if (uart->uart_dma_flag & RT_DEVICE_FLAG_DMA_RX)
             ctrl_arg = RT_DEVICE_FLAG_DMA_RX;
         else
             ctrl_arg = RT_DEVICE_FLAG_INT_RX;
     }
-    else if(ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING))
+    else if (ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING))
     {
         if (uart->uart_dma_flag & RT_DEVICE_FLAG_DMA_TX)
             ctrl_arg = RT_DEVICE_FLAG_DMA_TX;
@@ -250,7 +248,7 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
                 RT_ASSERT(0);
             }
         }
-        else if(ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
+        else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX)
         {
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC);
 
@@ -280,7 +278,6 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
     case RT_DEVICE_CTRL_CONFIG:
         if (ctrl_arg & (RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX))
         {
-
 #ifdef RT_SERIAL_USING_DMA
             stm32_dma_config(serial, ctrl_arg);
 #endif
@@ -289,20 +286,18 @@ static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *ar
             stm32_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)ctrl_arg);
         break;
 
-    case RT_DEVICE_CHECK_OPTMODE:
-        {
-            if (ctrl_arg & RT_DEVICE_FLAG_DMA_TX)
-                return RT_SERIAL_TX_BLOCKING_NO_BUFFER;
-            else
-                return RT_SERIAL_TX_BLOCKING_BUFFER;
-        }
+    case RT_DEVICE_CHECK_OPTMODE: {
+        if (ctrl_arg & RT_DEVICE_FLAG_DMA_TX)
+            return RT_SERIAL_TX_BLOCKING_NO_BUFFER;
+        else
+            return RT_SERIAL_TX_BLOCKING_BUFFER;
+    }
     case RT_DEVICE_CTRL_CLOSE:
-        if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK )
+        if (HAL_UART_DeInit(&(uart->handle)) != HAL_OK)
         {
             RT_ASSERT(0)
         }
         break;
-
     }
     return RT_EOK;
 }
@@ -327,11 +322,11 @@ rt_uint32_t stm32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity)
     {
         if (parity == UART_PARITY_NONE)
         {
-            mask = 0x00FFU ;
+            mask = 0x00FFU;
         }
         else
         {
-            mask = 0x007FU ;
+            mask = 0x007FU;
         }
     }
 #ifdef UART_WORDLENGTH_9B
@@ -339,11 +334,11 @@ rt_uint32_t stm32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity)
     {
         if (parity == UART_PARITY_NONE)
         {
-            mask = 0x01FFU ;
+            mask = 0x01FFU;
         }
         else
         {
-            mask = 0x00FFU ;
+            mask = 0x00FFU;
         }
     }
 #endif
@@ -352,11 +347,11 @@ rt_uint32_t stm32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity)
     {
         if (parity == UART_PARITY_NONE)
         {
-            mask = 0x007FU ;
+            mask = 0x007FU;
         }
         else
         {
-            mask = 0x003FU ;
+            mask = 0x003FU;
         }
     }
     else
@@ -369,7 +364,7 @@ rt_uint32_t stm32_uart_get_mask(rt_uint32_t word_length, rt_uint32_t parity)
 
 static int stm32_getc(struct rt_serial_device *serial)
 {
-    int ch;
+    int                ch;
     struct stm32_uart *uart;
     RT_ASSERT(serial != RT_NULL);
     uart = rt_container_of(serial, struct stm32_uart, serial);
@@ -380,10 +375,10 @@ static int stm32_getc(struct rt_serial_device *serial)
     return ch;
 }
 
-static rt_ssize_t stm32_transmit(struct rt_serial_device     *serial,
-                                       rt_uint8_t           *buf,
-                                       rt_size_t             size,
-                                       rt_uint32_t           tx_flag)
+static rt_ssize_t stm32_transmit(struct rt_serial_device *serial,
+                                 rt_uint8_t              *buf,
+                                 rt_size_t                size,
+                                 rt_uint32_t              tx_flag)
 {
     struct stm32_uart *uart;
 
@@ -393,11 +388,19 @@ static rt_ssize_t stm32_transmit(struct rt_serial_device     *serial,
 
     if (uart->uart_dma_flag & RT_DEVICE_FLAG_DMA_TX)
     {
-        HAL_UART_Transmit_DMA(&uart->handle, buf, size);
+        if (HAL_UART_Transmit_DMA(&uart->handle, buf, size) != HAL_OK)
+        {
+            return -RT_EIO;
+        }
+
         return size;
     }
 
-    stm32_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)tx_flag);
+    /* NOLINTNEXTLINE(performance-no-int-to-ptr) */
+    if (stm32_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)tx_flag) != RT_EOK)
+    {
+        return -RT_EIO;
+    }
 
     return size;
 }
@@ -406,7 +409,7 @@ static rt_ssize_t stm32_transmit(struct rt_serial_device     *serial,
 static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag)
 {
     struct stm32_uart *uart;
-    rt_size_t recv_len, counter;
+    rt_size_t          recv_len, counter;
 
     RT_ASSERT(serial != RT_NULL);
     uart = rt_container_of(serial, struct stm32_uart, serial);
@@ -419,16 +422,16 @@ static void dma_recv_isr(struct rt_serial_device *serial, rt_uint8_t isr_flag)
         recv_len = serial->config.dma_ping_bufsz + uart->dma_rx.remaining_cnt - counter;
     if (recv_len)
     {
-#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
         rt_uint8_t *ptr = NULL;
-        rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr);
+        rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, (void *)&ptr);
         SCB_InvalidateDCache_by_Addr((uint32_t *)ptr, serial->config.dma_ping_bufsz);
 #endif
         uart->dma_rx.remaining_cnt = counter;
         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
     }
 }
-#endif  /* RT_SERIAL_USING_DMA */
+#endif /* RT_SERIAL_USING_DMA */
 
 /**
  * Uart common interrupt process. This need add to uart ISR.
@@ -442,19 +445,23 @@ static void uart_isr(struct rt_serial_device *serial)
     RT_ASSERT(serial != RT_NULL);
     uart = rt_container_of(serial, struct stm32_uart, serial);
     /* If the Read data register is not empty and the RXNE interrupt is enabled  (RDR) */
-    if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) &&
-            (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET))
+    if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE)) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE)))
     {
-        char chr = UART_GET_RDR(&uart->handle, stm32_uart_get_mask(uart->handle.Init.WordLength, uart->handle.Init.Parity));
-        rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &chr);
-        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+        rt_uint8_t  chr;
+        rt_uint32_t rx_drain_limit = 1024;
+        rt_uint32_t mask           = stm32_uart_get_mask(uart->handle.Init.WordLength, uart->handle.Init.Parity);
+        do {
+            chr = UART_GET_RDR(&uart->handle, mask);
+            rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, (void *)&chr);
+            rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+            rx_drain_limit--;
+        } while (__HAL_UART_GET_FLAG(&uart->handle, UART_FLAG_RXNE) && rx_drain_limit > 0);
     }
     /* If the Transmit data register is empty and the TXE interrupt enable is enabled  (TDR) */
-    else if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE) != RESET) &&
-                (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TXE)) != RESET)
+    if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE)) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TXE)))
     {
         rt_uint8_t put_char = 0;
-        if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, &put_char) == RT_EOK)
+        if (rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GETC, (void *)&put_char) == RT_EOK)
         {
             UART_SET_TDR(&uart->handle, put_char);
         }
@@ -464,8 +471,7 @@ static void uart_isr(struct rt_serial_device *serial)
             __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_TC);
         }
     }
-    else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) &&
-            (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TC) != RESET))
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TC)))
     {
         if (uart->uart_dma_flag & RT_DEVICE_FLAG_DMA_TX)
         {
@@ -477,70 +483,56 @@ static void uart_isr(struct rt_serial_device *serial)
             /* Transmission complete interrupt disable ( CR1 Register) */
             __HAL_UART_DISABLE_IT(&(uart->handle), UART_IT_TC);
             rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
+            /* Clear Transmission complete interrupt flag ( ISR Register ) */
+            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
         }
-        /* Clear Transmission complete interrupt flag ( ISR Register ) */
-        UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
     }
 
 #ifdef RT_SERIAL_USING_DMA
-    else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET)
-             && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET))
+    if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE))
+        && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE)))
     {
         dma_recv_isr(serial, UART_RX_DMA_IT_IDLE_FLAG);
         __HAL_UART_CLEAR_IDLEFLAG(&uart->handle);
     }
 #endif
-    else
+
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_ORE))
     {
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_ORE) != RESET)
-        {
-            LOG_E("(%s) serial device Overrun error!", serial->parent.parent.name);
-            __HAL_UART_CLEAR_OREFLAG(&uart->handle);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE) != RESET)
-        {
-            __HAL_UART_CLEAR_NEFLAG(&uart->handle);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE) != RESET)
-        {
-            __HAL_UART_CLEAR_FEFLAG(&uart->handle);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE) != RESET)
-        {
-            __HAL_UART_CLEAR_PEFLAG(&uart->handle);
-        }
+        LOG_E("(%s) serial device Overrun error!", serial->parent.parent.name);
+        __HAL_UART_CLEAR_OREFLAG(&uart->handle);
+    }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE))
+    {
+        __HAL_UART_CLEAR_NEFLAG(&uart->handle);
+    }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE))
+    {
+        __HAL_UART_CLEAR_FEFLAG(&uart->handle);
+    }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE))
+    {
+        __HAL_UART_CLEAR_PEFLAG(&uart->handle);
+    }
 #if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) \
-    && !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7) \
-    && !defined(SOC_SERIES_STM32G4) && !defined(SOC_SERIES_STM32MP1) && !defined(SOC_SERIES_STM32WB) \
+    && !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7)                              \
+    && !defined(SOC_SERIES_STM32G4) && !defined(SOC_SERIES_STM32MP1) && !defined(SOC_SERIES_STM32WB)                             \
     && !defined(SOC_SERIES_STM32L5) && !defined(SOC_SERIES_STM32U5) && !defined(SOC_SERIES_STM32H5) && !defined(SOC_SERIES_STM32H7RS)
 #ifdef SOC_SERIES_STM32F3
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBDF) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBDF);
-        }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBDF))
+    {
+        UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBDF);
+    }
 #else
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBD) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBD);
-        }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBD))
+    {
+        UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBD);
+    }
 #endif
 #endif
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_CTS) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_CTS);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TXE);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC);
-        }
-        if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET)
-        {
-            UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_RXNE);
-        }
+    if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_CTS))
+    {
+        UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_CTS);
     }
 }
 
@@ -934,16 +926,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART1_INDEX].serial.config.tx_bufsz = BSP_UART1_TX_BUFSIZE;
 
 #ifdef BSP_UART1_RX_USING_DMA
-    uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz = BSP_UART1_DMA_PING_BUFSIZE;
-    uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart1_dma_rx = UART1_DMA_RX_CONFIG;
-    uart_config[UART1_INDEX].dma_rx = &uart1_dma_rx;
+    uart_obj[UART1_INDEX].serial.config.dma_ping_bufsz  = BSP_UART1_DMA_PING_BUFSIZE;
+    uart_obj[UART1_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart1_dma_rx               = UART1_DMA_RX_CONFIG;
+    uart_config[UART1_INDEX].dma_rx                     = &uart1_dma_rx;
 #endif
 
 #ifdef BSP_UART1_TX_USING_DMA
-    uart_obj[UART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart1_dma_tx = UART1_DMA_TX_CONFIG;
-    uart_config[UART1_INDEX].dma_tx = &uart1_dma_tx;
+    uart_obj[UART1_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart1_dma_tx  = UART1_DMA_TX_CONFIG;
+    uart_config[UART1_INDEX].dma_tx        = &uart1_dma_tx;
 #endif
 #endif
 
@@ -955,16 +947,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART2_INDEX].serial.config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
 
 #ifdef BSP_UART2_RX_USING_DMA
-    uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz = BSP_UART2_DMA_PING_BUFSIZE;
-    uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart2_dma_rx = UART2_DMA_RX_CONFIG;
-    uart_config[UART2_INDEX].dma_rx = &uart2_dma_rx;
+    uart_obj[UART2_INDEX].serial.config.dma_ping_bufsz  = BSP_UART2_DMA_PING_BUFSIZE;
+    uart_obj[UART2_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart2_dma_rx               = UART2_DMA_RX_CONFIG;
+    uart_config[UART2_INDEX].dma_rx                     = &uart2_dma_rx;
 #endif
 
 #ifdef BSP_UART2_TX_USING_DMA
-    uart_obj[UART2_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart2_dma_tx = UART2_DMA_TX_CONFIG;
-    uart_config[UART2_INDEX].dma_tx = &uart2_dma_tx;
+    uart_obj[UART2_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart2_dma_tx  = UART2_DMA_TX_CONFIG;
+    uart_config[UART2_INDEX].dma_tx        = &uart2_dma_tx;
 #endif
 #endif
 
@@ -976,16 +968,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART3_INDEX].serial.config.tx_bufsz = BSP_UART3_TX_BUFSIZE;
 
 #ifdef BSP_UART3_RX_USING_DMA
-    uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz = BSP_UART3_DMA_PING_BUFSIZE;
-    uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart3_dma_rx = UART3_DMA_RX_CONFIG;
-    uart_config[UART3_INDEX].dma_rx = &uart3_dma_rx;
+    uart_obj[UART3_INDEX].serial.config.dma_ping_bufsz  = BSP_UART3_DMA_PING_BUFSIZE;
+    uart_obj[UART3_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart3_dma_rx               = UART3_DMA_RX_CONFIG;
+    uart_config[UART3_INDEX].dma_rx                     = &uart3_dma_rx;
 #endif
 
 #ifdef BSP_UART3_TX_USING_DMA
-    uart_obj[UART3_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart3_dma_tx = UART3_DMA_TX_CONFIG;
-    uart_config[UART3_INDEX].dma_tx = &uart3_dma_tx;
+    uart_obj[UART3_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart3_dma_tx  = UART3_DMA_TX_CONFIG;
+    uart_config[UART3_INDEX].dma_tx        = &uart3_dma_tx;
 #endif
 #endif
 
@@ -997,16 +989,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART4_INDEX].serial.config.tx_bufsz = BSP_UART4_TX_BUFSIZE;
 
 #ifdef BSP_UART4_RX_USING_DMA
-    uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz = BSP_UART4_DMA_PING_BUFSIZE;
-    uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart4_dma_rx = UART4_DMA_RX_CONFIG;
-    uart_config[UART4_INDEX].dma_rx = &uart4_dma_rx;
+    uart_obj[UART4_INDEX].serial.config.dma_ping_bufsz  = BSP_UART4_DMA_PING_BUFSIZE;
+    uart_obj[UART4_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart4_dma_rx               = UART4_DMA_RX_CONFIG;
+    uart_config[UART4_INDEX].dma_rx                     = &uart4_dma_rx;
 #endif
 
 #ifdef BSP_UART4_TX_USING_DMA
-    uart_obj[UART4_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart4_dma_tx = UART4_DMA_TX_CONFIG;
-    uart_config[UART4_INDEX].dma_tx = &uart4_dma_tx;
+    uart_obj[UART4_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart4_dma_tx  = UART4_DMA_TX_CONFIG;
+    uart_config[UART4_INDEX].dma_tx        = &uart4_dma_tx;
 #endif
 #endif
 
@@ -1018,16 +1010,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART5_INDEX].serial.config.tx_bufsz = BSP_UART5_TX_BUFSIZE;
 
 #ifdef BSP_UART5_RX_USING_DMA
-    uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz = BSP_UART5_DMA_PING_BUFSIZE;
-    uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart5_dma_rx = UART5_DMA_RX_CONFIG;
-    uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx;
+    uart_obj[UART5_INDEX].serial.config.dma_ping_bufsz  = BSP_UART5_DMA_PING_BUFSIZE;
+    uart_obj[UART5_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart5_dma_rx               = UART5_DMA_RX_CONFIG;
+    uart_config[UART5_INDEX].dma_rx                     = &uart5_dma_rx;
 #endif
 
 #ifdef BSP_UART5_TX_USING_DMA
-    uart_obj[UART5_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart5_dma_tx = UART5_DMA_TX_CONFIG;
-    uart_config[UART5_INDEX].dma_tx = &uart5_dma_tx;
+    uart_obj[UART5_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart5_dma_tx  = UART5_DMA_TX_CONFIG;
+    uart_config[UART5_INDEX].dma_tx        = &uart5_dma_tx;
 #endif
 #endif
 
@@ -1039,16 +1031,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART6_INDEX].serial.config.tx_bufsz = BSP_UART6_TX_BUFSIZE;
 
 #ifdef BSP_UART6_RX_USING_DMA
-    uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz = BSP_UART6_DMA_PING_BUFSIZE;
-    uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart6_dma_rx = UART6_DMA_RX_CONFIG;
-    uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx;
+    uart_obj[UART6_INDEX].serial.config.dma_ping_bufsz  = BSP_UART6_DMA_PING_BUFSIZE;
+    uart_obj[UART6_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart6_dma_rx               = UART6_DMA_RX_CONFIG;
+    uart_config[UART6_INDEX].dma_rx                     = &uart6_dma_rx;
 #endif
 
 #ifdef BSP_UART6_TX_USING_DMA
-    uart_obj[UART6_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart6_dma_tx = UART6_DMA_TX_CONFIG;
-    uart_config[UART6_INDEX].dma_tx = &uart6_dma_tx;
+    uart_obj[UART6_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart6_dma_tx  = UART6_DMA_TX_CONFIG;
+    uart_config[UART6_INDEX].dma_tx        = &uart6_dma_tx;
 #endif
 #endif
 
@@ -1060,16 +1052,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART7_INDEX].serial.config.tx_bufsz = BSP_UART7_TX_BUFSIZE;
 
 #ifdef BSP_UART7_RX_USING_DMA
-    uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz = BSP_UART7_DMA_PING_BUFSIZE;
-    uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart7_dma_rx = UART7_DMA_RX_CONFIG;
-    uart_config[UART7_INDEX].dma_rx = &uart7_dma_rx;
+    uart_obj[UART7_INDEX].serial.config.dma_ping_bufsz  = BSP_UART7_DMA_PING_BUFSIZE;
+    uart_obj[UART7_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart7_dma_rx               = UART7_DMA_RX_CONFIG;
+    uart_config[UART7_INDEX].dma_rx                     = &uart7_dma_rx;
 #endif
 
 #ifdef BSP_UART7_TX_USING_DMA
-    uart_obj[UART7_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart7_dma_tx = UART7_DMA_TX_CONFIG;
-    uart_config[UART7_INDEX].dma_tx = &uart7_dma_tx;
+    uart_obj[UART7_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart7_dma_tx  = UART7_DMA_TX_CONFIG;
+    uart_config[UART7_INDEX].dma_tx        = &uart7_dma_tx;
 #endif
 #endif
 
@@ -1081,16 +1073,16 @@ static void stm32_uart_get_config(void)
     uart_obj[UART8_INDEX].serial.config.tx_bufsz = BSP_UART8_TX_BUFSIZE;
 
 #ifdef BSP_UART8_RX_USING_DMA
-    uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config uart8_dma_rx = UART8_DMA_RX_CONFIG;
-    uart_config[UART8_INDEX].dma_rx = &uart8_dma_rx;
+    uart_obj[UART8_INDEX].uart_dma_flag   |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config uart8_dma_rx  = UART8_DMA_RX_CONFIG;
+    uart_config[UART8_INDEX].dma_rx        = &uart8_dma_rx;
 #endif
 
 #ifdef BSP_UART8_TX_USING_DMA
-    uart_obj[UART8_INDEX].serial.config.dma_ping_bufsz = BSP_UART8_DMA_PING_BUFSIZE;
-    uart_obj[UART8_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_TX;
-    static struct dma_config uart8_dma_tx = UART8_DMA_TX_CONFIG;
-    uart_config[UART8_INDEX].dma_tx = &uart8_dma_tx;
+    uart_obj[UART8_INDEX].serial.config.dma_ping_bufsz  = BSP_UART8_DMA_PING_BUFSIZE;
+    uart_obj[UART8_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_TX;
+    static struct dma_config uart8_dma_tx               = UART8_DMA_TX_CONFIG;
+    uart_config[UART8_INDEX].dma_tx                     = &uart8_dma_tx;
 #endif
 #endif
 
@@ -1102,10 +1094,10 @@ static void stm32_uart_get_config(void)
     uart_obj[LPUART1_INDEX].serial.config.tx_bufsz = BSP_LPUART1_TX_BUFSIZE;
 
 #ifdef BSP_LPUART1_RX_USING_DMA
-    uart_obj[LPUART1_INDEX].serial.config.dma_ping_bufsz = BSP_LPUART1_DMA_PING_BUFSIZE;
-    uart_obj[LPUART1_INDEX].uart_dma_flag |= RT_DEVICE_FLAG_DMA_RX;
-    static struct dma_config lpuart1_dma_rx = LPUART1_DMA_CONFIG;
-    uart_config[LPUART1_INDEX].dma_rx = &lpuart1_dma_rx;
+    uart_obj[LPUART1_INDEX].serial.config.dma_ping_bufsz  = BSP_LPUART1_DMA_PING_BUFSIZE;
+    uart_obj[LPUART1_INDEX].uart_dma_flag                |= RT_DEVICE_FLAG_DMA_RX;
+    static struct dma_config lpuart1_dma_rx               = LPUART1_DMA_CONFIG;
+    uart_config[LPUART1_INDEX].dma_rx                     = &lpuart1_dma_rx;
 #endif
 #endif
 }
@@ -1141,7 +1133,7 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
         SET_BIT(RCC->AHBENR, dma_config->dma_rcc);
         tmpreg = READ_BIT(RCC->AHBENR, dma_config->dma_rcc);
 #elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) \
-    || defined(SOC_SERIES_STM32G4)|| defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB)
+    || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32WB)
         /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
         SET_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
         tmpreg = READ_BIT(RCC->AHB1ENR, dma_config->dma_rcc);
@@ -1158,7 +1150,7 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
         __HAL_RCC_DMAMUX_CLK_ENABLE();
 #endif
 
-        UNUSED(tmpreg);   /* To avoid compiler warnings */
+        UNUSED(tmpreg); /* To avoid compiler warnings */
     }
 
     if (RT_DEVICE_FLAG_DMA_RX == flag)
@@ -1170,15 +1162,15 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
         __HAL_LINKDMA(&(uart->handle), hdmatx, uart->dma_tx.handle);
     }
 
-#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5)
-    DMA_Handle->Instance                 = dma_config->Instance;
+#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5)
+    DMA_Handle->Instance = dma_config->Instance;
 #elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
-    DMA_Handle->Instance                 = dma_config->Instance;
-    DMA_Handle->Init.Channel             = dma_config->channel;
-#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)\
+    DMA_Handle->Instance     = dma_config->Instance;
+    DMA_Handle->Init.Channel = dma_config->channel;
+#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB) \
     || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
-    DMA_Handle->Instance                 = dma_config->Instance;
-    DMA_Handle->Init.Request             = dma_config->request;
+    DMA_Handle->Instance     = dma_config->Instance;
+    DMA_Handle->Init.Request = dma_config->request;
 #endif
     DMA_Handle->Init.PeriphInc           = DMA_PINC_DISABLE;
     DMA_Handle->Init.MemInc              = DMA_MINC_ENABLE;
@@ -1187,18 +1179,18 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
 
     if (RT_DEVICE_FLAG_DMA_RX == flag)
     {
-        DMA_Handle->Init.Direction           = DMA_PERIPH_TO_MEMORY;
-        DMA_Handle->Init.Mode                = DMA_CIRCULAR;
+        DMA_Handle->Init.Direction = DMA_PERIPH_TO_MEMORY;
+        DMA_Handle->Init.Mode      = DMA_CIRCULAR;
     }
     else if (RT_DEVICE_FLAG_DMA_TX == flag)
     {
-        DMA_Handle->Init.Direction           = DMA_MEMORY_TO_PERIPH;
-        DMA_Handle->Init.Mode                = DMA_NORMAL;
+        DMA_Handle->Init.Direction = DMA_MEMORY_TO_PERIPH;
+        DMA_Handle->Init.Mode      = DMA_NORMAL;
     }
 
-    DMA_Handle->Init.Priority            = DMA_PRIORITY_MEDIUM;
+    DMA_Handle->Init.Priority = DMA_PRIORITY_MEDIUM;
 #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
-    DMA_Handle->Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+    DMA_Handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 #endif
     if (HAL_DMA_DeInit(DMA_Handle) != HAL_OK)
     {
@@ -1214,7 +1206,7 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag)
     if (flag == RT_DEVICE_FLAG_DMA_RX)
     {
         rt_uint8_t *ptr = NULL;
-        rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, &ptr);
+        rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_GET_DMA_PING_BUF, (void *)&ptr);
 
         /* Start DMA transfer */
         if (HAL_UART_Receive_DMA(&(uart->handle), ptr, serial->config.dma_ping_bufsz) != HAL_OK)
@@ -1291,52 +1283,50 @@ void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
   */
 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
 {
-    struct stm32_uart *uart;
+    struct stm32_uart       *uart;
     struct rt_serial_device *serial;
-    rt_size_t trans_total_index;
-    rt_base_t level;
+    rt_size_t                trans_total_index;
+    rt_base_t                level;
 
     RT_ASSERT(huart != NULL);
-    uart = (struct stm32_uart *)huart;
+    uart   = (struct stm32_uart *)huart;
     serial = &uart->serial;
     RT_ASSERT(serial != RT_NULL);
 
-    level = rt_hw_interrupt_disable();
+    level             = rt_hw_interrupt_disable();
     trans_total_index = __HAL_DMA_GET_COUNTER(&(uart->dma_tx.handle));
     rt_hw_interrupt_enable(level);
 
     if (trans_total_index) return;
 
     rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE);
-
 }
-#endif  /* RT_SERIAL_USING_DMA */
+#endif /* RT_SERIAL_USING_DMA */
 
 static const struct rt_uart_ops stm32_uart_ops =
-{
-    .configure = stm32_configure,
-    .control = stm32_control,
-    .putc = stm32_putc,
-    .getc = stm32_getc,
-    .transmit = stm32_transmit
-};
+    {
+        .configure = stm32_configure,
+        .control   = stm32_control,
+        .putc      = stm32_putc,
+        .getc      = stm32_getc,
+        .transmit  = stm32_transmit};
 
 int rt_hw_usart_init(void)
 {
-    rt_err_t result = 0;
+    rt_err_t  result  = 0;
     rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
 
     stm32_uart_get_config();
     for (rt_uint32_t i = 0; i < obj_num; i++)
     {
         /* init UART object */
-        uart_obj[i].config = &uart_config[i];
+        uart_obj[i].config     = &uart_config[i];
         uart_obj[i].serial.ops = &stm32_uart_ops;
         /* register UART device */
         result = rt_hw_serial_register(&uart_obj[i].serial,
-                                        uart_obj[i].config->name,
-                                        RT_DEVICE_FLAG_RDWR,
-                                        NULL);
+                                       uart_obj[i].config->name,
+                                       RT_DEVICE_FLAG_RDWR,
+                                       NULL);
         RT_ASSERT(result == RT_EOK);
     }
 

+ 6 - 0
components/drivers/include/drivers/dev_serial_v2.h

@@ -210,6 +210,7 @@
 #define RT_SERIAL_CTRL_RX_FLUSH                 0x45    /* clear rx buffer. Discard all data */
 #define RT_SERIAL_CTRL_TX_FLUSH                 0x46    /* clear tx buffer. Blocking and wait for the send buffer data to be sent. not supported in poll mode */
 #define RT_SERIAL_CTRL_GET_UNREAD_BYTES_COUNT   0x47    /* get unread bytes count. not supported in poll mode */
+#define RT_SERIAL_CTRL_GET_CONFIG               0x48    /* get serial config */
 
 #define RT_SERIAL_ERR_OVERRUN           0x01
 #define RT_SERIAL_ERR_FRAMING           0x02
@@ -336,7 +337,12 @@ struct rt_serial_device
 #ifdef RT_USING_SERIAL_BYPASS
     struct rt_serial_bypass* bypass;
 #endif
+
     struct rt_device_notify rx_notify;
+
+#ifdef RT_USING_POSIX_STDIO
+    rt_bool_t is_posix_mode;
+#endif
 };
 
 /**

+ 230 - 173
components/drivers/serial/dev_serial_v2.c

@@ -61,9 +61,10 @@ static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
 /* fops for serial */
 static int serial_fops_open(struct dfs_file *fd)
 {
-    rt_err_t    ret   = 0;
-    rt_uint16_t flags = 0;
-    rt_device_t device;
+    rt_err_t                 ret   = 0;
+    rt_uint16_t              flags = 0;
+    rt_device_t              device;
+    struct rt_serial_device *serial;
 
     device = (rt_device_t)fd->vnode->data;
     RT_ASSERT(device != RT_NULL);
@@ -89,8 +90,14 @@ static int serial_fops_open(struct dfs_file *fd)
 
     if ((fd->flags & O_ACCMODE) != O_WRONLY)
         rt_device_set_rx_indicate(device, serial_fops_rx_ind);
+
+    rt_device_close(device);
     ret = rt_device_open(device, flags | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING);
-    if (ret == RT_EOK) return 0;
+    if (ret == RT_EOK)
+    {
+        serial                = (struct rt_serial_device *)device;
+        serial->is_posix_mode = RT_TRUE;
+    }
 
     return ret;
 }
@@ -125,6 +132,8 @@ static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
         fd->flags &= ~mask;
         fd->flags |= flags;
         break;
+    default:
+        break;
     }
 
     return rt_device_control(device, cmd, args);
@@ -204,13 +213,10 @@ static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t co
 
 static int serial_fops_flush(struct dfs_file *fd)
 {
-    rt_device_t              device;
-    struct rt_serial_device *serial;
-
+    rt_device_t device;
     device = (rt_device_t)fd->vnode->data;
     RT_ASSERT(device != RT_NULL);
 
-    serial = (struct rt_serial_device *)device;
     rt_device_control(device, RT_SERIAL_CTRL_TX_FLUSH, (void *)RT_NULL);
     rt_device_control(device, RT_SERIAL_CTRL_RX_FLUSH, (void *)RT_NULL);
 
@@ -379,8 +385,8 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev,
     int                      getc_element; /* Gets one byte of data received */
     rt_uint8_t              *getc_buffer;  /* Pointer to the receive data buffer */
 
-    if (size == 0) return 0;
     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
+    if (size == 0) return 0;
 
     serial      = (struct rt_serial_device *)dev;
     getc_buffer = (rt_uint8_t *)buffer;
@@ -389,7 +395,7 @@ rt_ssize_t _serial_poll_rx(struct rt_device *dev,
     while (size)
     {
         getc_element = serial->ops->getc(serial);
-        if (getc_element == -1) break;
+        if (getc_element < 0) break;
 
         *getc_buffer = getc_element;
 
@@ -424,6 +430,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
     struct rt_serial_device *serial;
     rt_size_t                putc_size;
     rt_uint8_t              *putc_buffer; /* Pointer to the transmit data buffer */
+    int                      putc_result;
 
     if (size == 0) return 0;
     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
@@ -441,7 +448,8 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
             if (*putc_buffer == '\n')
                 serial->ops->putc(serial, '\r');
         }
-        serial->ops->putc(serial, *putc_buffer);
+        putc_result = serial->ops->putc(serial, *putc_buffer);
+        if (putc_result < 0) break;
 
         ++putc_buffer;
         --size;
@@ -461,7 +469,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
   * @param pos Empty parameter.
   * @param buffer Receive data buffer.
   * @param size Receive data buffer length.
-  * @return Returns the actual length of data received. If a timeout occurs in blocking mode, it returns -RT_ETIMEOUT.
+  * @return Returns the actual length of data received.
   */
 static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
                                   rt_off_t          pos,
@@ -482,15 +490,15 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
     if (dev->open_flag & RT_SERIAL_RX_BLOCKING)
     {
         rt_size_t  data_len;
-        rt_tick_t  now_tick;
+        rt_tick_t  delta_tick;
         rt_size_t  rx_bufsz_third  = serial->config.rx_bufsz / 2;
         rt_int32_t base_rx_timeout = rt_atomic_load(&rx_fifo->rx_timeout);
-        rt_int32_t rx_timeout      = base_rx_timeout;
+        rt_int32_t rx_timeout_left = base_rx_timeout;
         rt_tick_t  begin_tick      = rt_tick_get();
 
         while (1)
         {
-            if (rx_timeout != RT_WAITING_NO)
+            if (rx_timeout_left != RT_WAITING_NO)
             {
                 level    = rt_spin_lock_irqsave(&serial->spinlock);
                 data_len = rt_ringbuffer_data_len(&rx_fifo->rb);
@@ -512,26 +520,24 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
             level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
             recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
             RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
-            if (recv_size == size || rx_timeout == RT_WAITING_NO)
+            if (recv_size == size || rx_timeout_left == RT_WAITING_NO)
             {
                 break;
             }
 
-            rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout);
-            if (rx_timeout != RT_WAITING_FOREVER)
+            rt_completion_wait(&rx_fifo->rx_cpt, rx_timeout_left);
+            if (rx_timeout_left != RT_WAITING_FOREVER)
             {
-                now_tick = rt_tick_get();
-                if (now_tick - begin_tick >= base_rx_timeout)
+                delta_tick = rt_tick_get_delta(begin_tick);
+                if (delta_tick >= base_rx_timeout)
                 {
-                    return -RT_ETIMEOUT;
-                }
-                else
-                {
-                    if (now_tick > begin_tick)
-                        rx_timeout = base_rx_timeout - (now_tick - begin_tick);
-                    else
-                        rx_timeout = begin_tick + base_rx_timeout - now_tick + 1;
+                    level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
+                    recv_size += rt_ringbuffer_get(&rx_fifo->rb, (rt_uint8_t *)buffer + recv_size, size - recv_size);
+                    RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
+                    return recv_size;
                 }
+
+                rx_timeout_left = base_rx_timeout - delta_tick;
             }
         }
     }
@@ -554,7 +560,7 @@ static rt_ssize_t _serial_fifo_rx(struct rt_device *dev,
   * @param pos Empty parameter.
   * @param buffer Transmit data buffer.
   * @param size Transmit data buffer length.
-  * @return Returns the actual length of data transmitted. If a timeout occurs, it returns -RT_ETIMEOUT.
+  * @return Returns the actual length of data transmitted.
   */
 static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
                                                 rt_off_t          pos,
@@ -594,28 +600,29 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
                                       (rt_uint8_t *)buffer,
                                       size,
                                       RT_SERIAL_TX_BLOCKING);
+    if (send_size <= 0)
+    {
+        return 0;
+    }
 
     if (rt_atomic_load(&tx_fifo->tx_timeout) == RT_WAITING_NO)
     {
-        return send_size;
+        /* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
+#ifdef RT_USING_POSIX_STDIO
+        if (serial->is_posix_mode)
+            return send_size;
+#endif
+        return 0;
     }
 
     /* Waiting for the transmission to complete */
     ret = rt_completion_wait(&tx_fifo->tx_cpt, rt_atomic_load(&tx_fifo->tx_timeout));
     if (ret != RT_EOK)
     {
-        if (ret == -RT_ETIMEOUT)
-        {
-            return ret;
-        }
-        else
-        {
-            return 0;
-        }
+        /* Cannot get the number of bytes sent under DMA, so returns 0 directly */
+        return 0;
     }
 
-    /* Inactive tx mode flag */
-    rt_atomic_flag_clear(&tx_fifo->activated);
     return send_size;
 }
 
@@ -626,7 +633,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
   * @param pos Empty parameter.
   * @param buffer Transmit data buffer.
   * @param size Transmit data buffer length.
-  * @return Returns the final length of data transmitted. If not all data can be sent within the timeout period, returns -RT_ETIMEOUT.
+  * @return Returns the final length of data transmitted.
   */
 static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
                                                rt_off_t          pos,
@@ -657,11 +664,13 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
         return 0;
     }
 
-    rt_tick_t  now_tick;
+    rt_tick_t  delta_tick;
     rt_int32_t base_tx_timeout = rt_atomic_load(&tx_fifo->tx_timeout);
-    rt_int32_t tx_timeout      = base_tx_timeout;
+    rt_int32_t tx_timeout_left = base_tx_timeout;
     rt_tick_t  begin_tick      = rt_tick_get();
     rt_size_t  send_size       = 0;
+    rt_size_t  rb_size;
+    rt_ssize_t transmit_size;
 
     while (send_size != size)
     {
@@ -671,6 +680,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
         tx_fifo->put_size = rt_ringbuffer_put(&tx_fifo->rb,
                                               (rt_uint8_t *)buffer + send_size,
                                               size - send_size);
+        rb_size           = rt_ringbuffer_data_len(&tx_fifo->rb);
         RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
 
         /* clear tx_cpt flag */
@@ -679,39 +689,44 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
         /* Call the transmit interface for transmission again */
         /* Note that in interrupt mode, buffer and tx_fifo->put_size
          * are inactive parameters */
-        serial->ops->transmit(serial,
-                              (rt_uint8_t *)buffer + send_size,
-                              tx_fifo->put_size,
-                              RT_SERIAL_TX_BLOCKING);
-
-        send_size += tx_fifo->put_size;
+        transmit_size = serial->ops->transmit(serial,
+                                              (rt_uint8_t *)buffer + send_size,
+                                              tx_fifo->put_size,
+                                              RT_SERIAL_TX_BLOCKING);
+        if (transmit_size <= 0)
+        {
+            return send_size;
+        }
 
-        if (tx_timeout == RT_WAITING_NO)
+        if (tx_timeout_left == RT_WAITING_NO)
         {
+            /* The implementation of POSIX nonblock mode is to set tx_timeout to RT_WAITING_NO */
+#ifdef RT_USING_POSIX_STDIO
+            if (serial->is_posix_mode)
+                send_size += tx_fifo->put_size;
+#endif
             break;
         }
 
         /* Waiting for the transmission to complete */
-        rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout);
-        if (tx_timeout != RT_WAITING_FOREVER)
+        rt_completion_wait(&tx_fifo->tx_cpt, tx_timeout_left);
+        if (tx_timeout_left != RT_WAITING_FOREVER)
         {
-            now_tick = rt_tick_get();
-            if (now_tick - begin_tick >= base_tx_timeout)
-            {
-                return -RT_ETIMEOUT;
-            }
-            else
+            delta_tick = rt_tick_get_delta(begin_tick);
+            if (delta_tick >= base_tx_timeout)
             {
-                if (now_tick > begin_tick)
-                    tx_timeout = base_tx_timeout - (now_tick - begin_tick);
-                else
-                    tx_timeout = begin_tick + base_tx_timeout - now_tick + 1;
+                level      = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
+                send_size += rb_size - rt_ringbuffer_data_len(&tx_fifo->rb);
+                RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
+                return send_size;
             }
+
+            tx_timeout_left = base_tx_timeout - delta_tick;
         }
+
+        send_size += tx_fifo->put_size;
     }
 
-    /* Finally Inactivate the tx->fifo */
-    rt_atomic_flag_clear(&tx_fifo->activated);
 
     return send_size;
 }
@@ -734,7 +749,8 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
     struct rt_serial_tx_fifo *tx_fifo;
     rt_uint8_t               *put_ptr;
     rt_base_t                 level;
-    rt_size_t                 send_size = 0;
+    rt_size_t                 send_size;
+    rt_ssize_t                transmit_size;
 
     if (size == 0) return 0;
     RT_ASSERT(dev != RT_NULL && buffer != RT_NULL);
@@ -761,10 +777,14 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
         /* Call the transmit interface for transmission again */
         /* Note that in interrupt mode, put_ptr and tx_fifo->put_size
          * are inactive parameters */
-        serial->ops->transmit(serial,
-                              put_ptr,
-                              tx_fifo->put_size,
-                              RT_SERIAL_TX_NON_BLOCKING);
+        transmit_size = serial->ops->transmit(serial,
+                                              put_ptr,
+                                              tx_fifo->put_size,
+                                              RT_SERIAL_TX_NON_BLOCKING);
+        if (transmit_size <= 0)
+        {
+            return 0;
+        }
         /* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait
          * for the rt_current_thread to resume */
         return send_size;
@@ -794,7 +814,8 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
                                     rt_uint16_t       tx_oflag)
 {
     struct rt_serial_device  *serial;
-    struct rt_serial_tx_fifo *tx_fifo = RT_NULL;
+    struct rt_serial_tx_fifo *tx_fifo        = RT_NULL;
+    rt_err_t                  control_result = RT_EOK;
 
     RT_ASSERT(dev != RT_NULL);
     serial = (struct rt_serial_device *)dev;
@@ -824,11 +845,16 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
     {
         /* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine
          * whether serial device needs to use buffer */
-        rt_err_t optmode; /* The operating mode used by serial device */
         /* Call the Control() API to get the operating mode */
-        optmode = serial->ops->control(serial,
-                                       RT_DEVICE_CHECK_OPTMODE,
-                                       (void *)RT_DEVICE_FLAG_TX_BLOCKING);
+        control_result = serial->ops->control(serial,
+                                              RT_DEVICE_CHECK_OPTMODE,
+                                              (void *)RT_DEVICE_FLAG_TX_BLOCKING);
+        if (control_result < 0)
+        {
+            return control_result;
+        }
+
+        rt_err_t optmode = control_result;
         if (optmode == RT_SERIAL_TX_BLOCKING_BUFFER)
         {
             /* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */
@@ -844,7 +870,7 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
             dev->write = _serial_fifo_tx_blocking_buf;
 #endif
         }
-        else
+        else if (optmode == RT_SERIAL_TX_BLOCKING_NO_BUFFER)
         {
             /* If not use RT_SERIAL_TX_BLOCKING_BUFFER,
              * the control() API is called to configure the serial device */
@@ -860,9 +886,17 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
 #endif
 
             /* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/
-            serial->ops->control(serial,
-                                 RT_DEVICE_CTRL_CONFIG,
-                                 (void *)RT_SERIAL_TX_BLOCKING);
+            control_result = serial->ops->control(serial,
+                                                  RT_DEVICE_CTRL_CONFIG,
+                                                  (void *)RT_SERIAL_TX_BLOCKING);
+            if (control_result < 0)
+            {
+                goto __exit;
+            }
+        }
+        else
+        {
+            return -RT_EIO;
         }
         rt_atomic_flag_clear(&tx_fifo->activated);
         tx_fifo->put_size = 0;
@@ -897,11 +931,12 @@ static rt_err_t rt_serial_tx_enable(struct rt_device *dev,
     dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING;
 
     /* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/
-    serial->ops->control(serial,
-                         RT_DEVICE_CTRL_CONFIG,
-                         (void *)RT_SERIAL_TX_NON_BLOCKING);
+    control_result = serial->ops->control(serial,
+                                          RT_DEVICE_CTRL_CONFIG,
+                                          (void *)RT_SERIAL_TX_NON_BLOCKING);
 
-    return RT_EOK;
+__exit:
+    return control_result;
 }
 
 
@@ -974,11 +1009,7 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev,
     {
         dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING;
         /* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/
-        serial->ops->control(serial,
-                             RT_DEVICE_CTRL_CONFIG,
-                             (void *)RT_SERIAL_RX_NON_BLOCKING);
-
-        return RT_EOK;
+        return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_NON_BLOCKING);
     }
 
     /* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */
@@ -988,11 +1019,7 @@ static rt_err_t rt_serial_rx_enable(struct rt_device *dev,
     rt_completion_init(&rx_fifo->rx_cpt);
     dev->open_flag |= RT_SERIAL_RX_BLOCKING;
     /* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/
-    serial->ops->control(serial,
-                         RT_DEVICE_CTRL_CONFIG,
-                         (void *)RT_SERIAL_RX_BLOCKING);
-
-    return RT_EOK;
+    return serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_SERIAL_RX_BLOCKING);
 }
 
 /**
@@ -1016,23 +1043,27 @@ static rt_err_t rt_serial_rx_disable(struct rt_device *dev,
 
     if (serial->serial_rx == RT_NULL) return RT_EOK;
 
+    rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+    RT_ASSERT(rx_fifo != RT_NULL);
+
     if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING)
     {
         dev->open_flag &= ~RT_SERIAL_RX_NON_BLOCKING;
+        /* disable ignore return value */
         serial->ops->control(serial,
                              RT_DEVICE_CTRL_CLR_INT,
                              (void *)RT_SERIAL_RX_NON_BLOCKING);
     }
     else
     {
+        rt_completion_done(&rx_fifo->rx_cpt);
         dev->open_flag &= ~RT_SERIAL_RX_BLOCKING;
+        /* disable ignore return value */
         serial->ops->control(serial,
                              RT_DEVICE_CTRL_CLR_INT,
                              (void *)RT_SERIAL_RX_BLOCKING);
     }
 
-    rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
-    RT_ASSERT(rx_fifo != RT_NULL);
     rt_free(rx_fifo);
     serial->serial_rx = RT_NULL;
 
@@ -1066,7 +1097,7 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev,
     if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING)
     {
         dev->open_flag &= ~RT_SERIAL_TX_NON_BLOCKING;
-
+        /* disable ignore return value */
         serial->ops->control(serial,
                              RT_DEVICE_CTRL_CLR_INT,
                              (void *)RT_SERIAL_TX_NON_BLOCKING);
@@ -1075,6 +1106,7 @@ static rt_err_t rt_serial_tx_disable(struct rt_device *dev,
     {
         rt_completion_done(&tx_fifo->tx_cpt);
         dev->open_flag &= ~RT_SERIAL_TX_BLOCKING;
+        /* disable ignore return value */
         serial->ops->control(serial,
                              RT_DEVICE_CTRL_CLR_INT,
                              (void *)RT_SERIAL_TX_BLOCKING);
@@ -1111,6 +1143,36 @@ static rt_err_t rt_serial_init(struct rt_device *dev)
     return result;
 }
 
+/**
+  * @brief Close the serial device.
+  * @param dev The pointer of device driver structure
+  * @return Return the status of the operation.
+  */
+static rt_err_t rt_serial_close(struct rt_device *dev)
+{
+    struct rt_serial_device *serial;
+
+    RT_ASSERT(dev != RT_NULL);
+    serial = (struct rt_serial_device *)dev;
+
+    /* Disable serial receive mode. */
+    rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
+    /* Disable serial tranmit mode. */
+    rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
+
+    /* Clear the callback function */
+    serial->parent.rx_indicate = RT_NULL;
+    serial->parent.tx_complete = RT_NULL;
+
+    rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify));
+
+    /* Call the control() API to close the serial device. disable ignore return value */
+    serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
+    dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
+
+    return RT_EOK;
+}
+
 /**
   * @brief Open the serial device.
   * @param dev The pointer of device driver structure
@@ -1120,19 +1182,12 @@ static rt_err_t rt_serial_init(struct rt_device *dev)
 static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
 {
     struct rt_serial_device *serial;
+    rt_err_t                 result = RT_EOK;
 
     RT_ASSERT(dev != RT_NULL);
     serial = (struct rt_serial_device *)dev;
 
-    /* Check that the device has been turned on */
-    if ((dev->open_flag) & (15 << 12))
-    {
-        LOG_D("(%s) serial device has already been opened, it will run in its original configuration", dev->parent.name);
-        return RT_EOK;
-    }
-
-    LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
-          dev, oflag);
+    LOG_D("open serial device: 0x%08x with open flag: 0x%04x", dev, oflag);
 
     /* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */
     if ((oflag & RT_SERIAL_RX_BLOCKING) == RT_SERIAL_RX_BLOCKING)
@@ -1152,48 +1207,31 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
 
     /* initialize the Rx structure according to open flag */
     if (serial->serial_rx == RT_NULL)
-        rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
+    {
+        result = rt_serial_rx_enable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
+        if (result != RT_EOK)
+        {
+            rt_serial_close(dev);
+            goto __exit;
+        }
+    }
 
     /* initialize the Tx structure according to open flag */
     if (serial->serial_tx == RT_NULL)
-        rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
+    {
+        result = rt_serial_tx_enable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
+        if (result != RT_EOK)
+        {
+            rt_serial_close(dev);
+            goto __exit;
+        }
+    }
 
-    return RT_EOK;
+__exit:
+    return result;
 }
 
 
-/**
-  * @brief Close the serial device.
-  * @param dev The pointer of device driver structure
-  * @return Return the status of the operation.
-  */
-static rt_err_t rt_serial_close(struct rt_device *dev)
-{
-    struct rt_serial_device *serial;
-
-    RT_ASSERT(dev != RT_NULL);
-    serial = (struct rt_serial_device *)dev;
-
-    /* this device has more reference count */
-    if (dev->ref_count > 1) return -RT_ERROR;
-    /* Disable serial receive mode. */
-    rt_serial_rx_disable(dev, dev->open_flag & (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING));
-    /* Disable serial tranmit mode. */
-    rt_serial_tx_disable(dev, dev->open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
-
-    /* Clear the callback function */
-    serial->parent.rx_indicate = RT_NULL;
-    serial->parent.tx_complete = RT_NULL;
-
-    rt_memset(&serial->rx_notify, RT_NULL, sizeof(struct rt_device_notify));
-
-    /* Call the control() API to close the serial device */
-    serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
-    dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
-
-    return RT_EOK;
-}
-
 static void _serial_rx_flush(struct rt_serial_device *serial)
 {
     rt_base_t                 level;
@@ -1202,8 +1240,10 @@ static void _serial_rx_flush(struct rt_serial_device *serial)
 
     if (serial->config.rx_bufsz == 0)
     {
-        while (serial->ops->getc(serial) != -1)
+        rt_uint32_t rx_flush_limit = 0xFFFFFFF;
+        while (serial->ops->getc(serial) != -1 && rx_flush_limit > 0)
         {
+            rx_flush_limit--;
         }
     }
     else
@@ -1235,7 +1275,6 @@ static void _serial_tx_flush(struct rt_serial_device *serial)
         if (rt_atomic_load(&tx_fifo->activated))
         {
             rt_completion_wait(&tx_fifo->tx_cpt, RT_WAITING_FOREVER);
-            return;
         }
     }
 }
@@ -1252,15 +1291,14 @@ static rt_err_t _serial_get_unread_bytes_count(struct rt_serial_device *serial,
         *unread_bytes = -1;
         return -RT_EPERM;
     }
-    else
-    {
-        rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
-        RT_ASSERT(rx_fifo != RT_NULL);
 
-        level         = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
-        *unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb);
-        RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
-    }
+    rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+    RT_ASSERT(rx_fifo != RT_NULL);
+
+    level         = RT_SERIAL_FIFO_LOCK(&serial->spinlock);
+    *unread_bytes = rt_ringbuffer_data_len(&rx_fifo->rb);
+    RT_SERIAL_FIFO_UNLOCK(&serial->spinlock, level);
+
     return RT_EOK;
 }
 
@@ -1384,6 +1422,17 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
             serial->ops->configure(serial, (struct serial_configure *)args);
         }
         break;
+    case RT_SERIAL_CTRL_GET_CONFIG:
+        if (args == RT_NULL)
+        {
+            ret = -RT_EINVAL;
+        }
+        else
+        {
+            struct serial_configure *pconfig = (struct serial_configure *)args;
+            *pconfig                         = serial->config;
+        }
+        break;
     case RT_DEVICE_CTRL_NOTIFY_SET:
         if (args == RT_NULL)
         {
@@ -1402,7 +1451,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
         }
         else
         {
-            *(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM;
+            *(rt_uint16_t *)args = RT_DEVICE_FLAG_RDWR | RT_SERIAL_RX_BLOCKING | RT_SERIAL_TX_BLOCKING | RT_DEVICE_FLAG_STREAM;
         }
         break;
 
@@ -1944,21 +1993,17 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
 #ifdef RT_SERIAL_BUF_STRATEGY_DROP
             rt_uint8_t *ptr;
             rt_size_t   size;
-            rt_size_t   space_len;
+            rt_size_t   put_len;
             /* UART_IT_IDLE and dma isr */
             level = rt_spin_lock_irqsave(&serial->spinlock);
             do
             {
-                space_len = rt_ringbuffer_space_len(&rx_fifo->rb);
-                if (space_len == 0)
-                    break;
-
                 rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
 
                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
 
-                space_len -= rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
-                if (space_len == 0)
+                put_len = rt_ringbuffer_put(&rx_fifo->rb, ptr, size);
+                if (put_len != size)
                     break;
 
                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
@@ -1973,9 +2018,10 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
             rt_size_t   size;
             /* UART_IT_IDLE and dma isr */
             level = rt_spin_lock_irqsave(&serial->spinlock);
-            rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
             do
             {
+                rt_serial_update_write_index(&rx_fifo->dma_ping_rb, rx_length);
+
                 size = rt_ringbuffer_peek(&rx_fifo->dma_ping_rb, &ptr);
 
                 rt_ringbuffer_put_force(&rx_fifo->rb, ptr, size);
@@ -2022,8 +2068,9 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
     /* Interrupt transmit event */
     case RT_SERIAL_EVENT_TX_DONE: {
         struct rt_serial_tx_fifo *tx_fifo;
-        rt_size_t                 tx_length = 0;
-        tx_fifo                             = (struct rt_serial_tx_fifo *)serial->serial_tx;
+        rt_size_t                 tx_length;
+        rt_ssize_t                transmit_size;
+        tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
         RT_ASSERT(tx_fifo != RT_NULL);
 
         /* Get the length of the data from the ringbuffer */
@@ -2049,22 +2096,28 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
         /* Call the transmit interface for transmission again */
         /* Note that in interrupt mode, tx_fifo->buffer and tx_length
          * are inactive parameters */
-        serial->ops->transmit(serial,
-                              tx_fifo->rb.buffer_ptr,
-                              tx_length,
-                              serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
+        transmit_size = serial->ops->transmit(serial,
+                                              tx_fifo->rb.buffer_ptr,
+                                              tx_length,
+                                              serial->parent.open_flag & (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING));
+        if (transmit_size <= 0)
+        {
+            rt_atomic_flag_clear(&tx_fifo->activated);
+        }
         break;
     }
 
 #ifdef RT_SERIAL_USING_DMA
     case RT_SERIAL_EVENT_TX_DMADONE: {
         struct rt_serial_tx_fifo *tx_fifo;
-        rt_size_t                 tx_length = 0;
-        tx_fifo                             = (struct rt_serial_tx_fifo *)serial->serial_tx;
+        rt_size_t                 tx_length;
+        rt_ssize_t                transmit_size;
+        tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx;
         RT_ASSERT(tx_fifo != RT_NULL);
-        if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING || rt_ringbuffer_get_size(&tx_fifo->rb) != 0)
+        /* nonblock */
+        if ((serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) != RT_SERIAL_TX_BLOCKING)
         {
-            // 每次进来中断就说明之前的put_size已经被发送完毕了
+            /* Each interruption upon entry indicates that the previous `put_size` has already been sent completely */
             rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size);
 
             /* Get the length of the data from the ringbuffer */
@@ -2076,15 +2129,19 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
                  * then call the transmit interface for transmission again */
                 rt_atomic_flag_test_and_set(&tx_fifo->activated);
 
-                rt_uint8_t *put_ptr = RT_NULL;
+                rt_uint8_t *put_ptr;
                 /* Get the linear length buffer from ringbuffer */
                 tx_fifo->put_size = rt_serial_get_linear_buffer(&tx_fifo->rb, &put_ptr);
 
                 /* Call the transmit interface for transmission again */
-                serial->ops->transmit(serial,
-                                      put_ptr,
-                                      tx_fifo->put_size,
-                                      RT_SERIAL_TX_NON_BLOCKING);
+                transmit_size = serial->ops->transmit(serial,
+                                                      put_ptr,
+                                                      tx_fifo->put_size,
+                                                      RT_SERIAL_TX_NON_BLOCKING);
+                if (transmit_size <= 0)
+                {
+                    rt_atomic_flag_clear(&tx_fifo->activated);
+                }
                 break;
             }
         }

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c

@@ -115,7 +115,7 @@ static void uart_rec_entry(void *parameter)
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_calloc(1, rev_len + 1);
     rt_int32_t  cnt, i;
     rt_uint8_t  last_old_data;
     rt_bool_t   fisrt_flag         = RT_TRUE;

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c

@@ -108,7 +108,7 @@ static rt_err_t uart_api()
         goto __exit;
     }
 
-    uart_write_buffer = (rt_uint8_t *)rt_malloc(sizeof(rt_uint8_t) * 100);
+    uart_write_buffer = (rt_uint8_t *)rt_malloc(100);
 
     for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
     {

+ 0 - 1
examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c

@@ -51,7 +51,6 @@ static rt_bool_t block_read(rt_device_t uart_dev)
 
     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));
-    rt_thread_mdelay(1000);
 
     rt_sprintf(log_buffer, "BLOCKING READ END");
     rt_device_write(uart_dev, 0, log_buffer, rt_strlen(log_buffer));

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c

@@ -83,7 +83,7 @@ static rt_bool_t block_write(rt_device_t uart_dev)
     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);
+        rt_thread_mdelay(10);
     }
 
     return RT_TRUE;

+ 43 - 4
examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c

@@ -31,10 +31,26 @@ static rt_err_t uart_find(void)
     return RT_EOK;
 }
 
-static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size)
+static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
 {
-    rt_device_write(&serial->parent, 0, uart_write_buffer, size);
-    rt_thread_mdelay(size * 0.0868 + 5);
+    rt_uint8_t  readBuf[16] = {0};
+    rt_uint32_t readSize    = 0;
+    if (send_size >= sizeof(readBuf))
+    {
+        readSize = sizeof(readBuf);
+    }
+    else
+    {
+        readSize = send_size;
+    }
+
+    rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+    if (size != send_size)
+    {
+        LOG_E("size [%4d], send_size [%4d]", size, send_size);
+        return -RT_ERROR;
+    }
+    rt_thread_mdelay(send_size * 0.0868 + 5);
     if (1 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1))
     {
         LOG_E("read failed.");
@@ -48,6 +64,25 @@ static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t size)
         return -RT_ERROR;
     }
 
+    /* Resend the data and check for any discrepancies upon reception */
+    if (readSize > 0)
+    {
+        rt_device_write(&serial->parent, 0, uart_write_buffer, readSize);
+        rt_thread_mdelay(readSize * 0.0868 + 5);
+        rt_device_read(&serial->parent, 0, readBuf, readSize);
+
+        for (rt_uint32_t i = 0; i < readSize; i++)
+        {
+            if (readBuf[i] != uart_write_buffer[i])
+            {
+                LOG_E("index: %d, Read Different data -> former data: %x, current data: %x.", i, uart_write_buffer[i], readBuf[i]);
+                return -RT_ERROR;
+            }
+        }
+    }
+
+    LOG_I("flush rx send_size [%4d]", send_size);
+
     return RT_EOK;
 }
 
@@ -80,7 +115,11 @@ static rt_bool_t uart_api()
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE * 5 + 1);
+    for (rt_uint32_t count = 0; count < (RT_SERIAL_TC_RXBUF_SIZE * 5 + 1); count++)
+    {
+        uart_write_buffer[count] = count;
+    }
 
     srand(rt_tick_get());
     for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)

+ 44 - 6
examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c

@@ -37,18 +37,34 @@ static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
     rt_tick_t   tick_diff;
     rt_tick_t   expect_time = send_size * 0.0868;
 
+    rt_uint8_t  readBuf[16] = {0};
+    rt_uint32_t readSize    = 0;
+    if (send_size >= sizeof(readBuf))
+    {
+        readSize = sizeof(readBuf);
+    }
+    else
+    {
+        readSize = send_size;
+    }
+
     /* 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);
+    old_tick        = rt_tick_get();
+    rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+    if (size != send_size)
+    {
+        LOG_E("size [%4d], send_size [%4d]", size, send_size);
+        return -RT_ERROR;
+    }
     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)
+    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;
@@ -58,6 +74,24 @@ static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
         LOG_I("send_size [%4d], time required for TXB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
     }
 
+    /* Resend the data and check for any discrepancies upon reception */
+    if (readSize > 0)
+    {
+        rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
+        rt_device_write(&serial->parent, 0, uart_write_buffer, readSize);
+        rt_device_read(&serial->parent, 0, readBuf, readSize);
+
+        for (rt_uint32_t i = 0; i < readSize; i++)
+        {
+            if (readBuf[i] != uart_write_buffer[i])
+            {
+                LOG_E("index: %d, Read Different data -> former data: %x, current data: %x.", i, uart_write_buffer[i], readBuf[i]);
+                return -RT_ERROR;
+            }
+        }
+    }
+
+
     return RT_EOK;
 }
 
@@ -81,7 +115,7 @@ static rt_bool_t uart_api()
 #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);
+    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.");
@@ -90,8 +124,12 @@ static rt_bool_t uart_api()
 
     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_int32_t  tx_timeout = 10 * 1000;
+    uart_write_buffer      = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_TXBUF_SIZE * 5 + 10);
+    for (rt_uint32_t count = 0; count < (RT_SERIAL_TC_TXBUF_SIZE * 5 + 10); count++)
+    {
+        uart_write_buffer[count] = count;
+    }
 
     rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
 

+ 43 - 5
examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c

@@ -36,6 +36,16 @@ 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;
+    rt_uint8_t  readBuf[16] = {0};
+    rt_uint32_t readSize    = 0;
+    if (send_size >= sizeof(readBuf))
+    {
+        readSize = sizeof(readBuf);
+    }
+    else
+    {
+        readSize = send_size;
+    }
 
     /* In interrupt mode, ticks may be inaccurate; compensation should be applied */
     if (send_size > 384)
@@ -43,11 +53,18 @@ static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
         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);
+    old_tick        = rt_tick_get();
+    rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+    if (size != send_size)
+    {
+        LOG_E("size [%4d], send_size [%4d]", size, send_size);
+        return -RT_ERROR;
+    }
+
     rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
     tick_diff = rt_tick_get() - old_tick;
-    if (tick_diff < expect_time)
+
+    if (tick_diff < expect_time || tick_diff > (expect_time + 10))
     {
         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;
@@ -57,6 +74,23 @@ static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
         LOG_I("send_size [%4d], time required for TXNB mode transmission to complete [%3d], expect_time [%3d]", send_size, tick_diff, expect_time);
     }
 
+    /* Resend the data and check for any discrepancies upon reception */
+    if (readSize > 0)
+    {
+        rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
+        rt_device_write(&serial->parent, 0, uart_write_buffer, readSize);
+        rt_device_read(&serial->parent, 0, readBuf, readSize);
+
+        for (rt_uint32_t i = 0; i < readSize; i++)
+        {
+            if (readBuf[i] != uart_write_buffer[i])
+            {
+                LOG_E("index: %d, Read Different data -> former data: %x, current data: %x.", i, uart_write_buffer[i], readBuf[i]);
+                return -RT_ERROR;
+            }
+        }
+    }
+
     return RT_EOK;
 }
 
@@ -80,7 +114,7 @@ static rt_bool_t uart_api()
 #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);
+    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.");
@@ -90,7 +124,11 @@ static rt_bool_t uart_api()
     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));
+    uart_write_buffer      = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE * 5 + 10);
+    for (rt_uint32_t count = 0; count < (RT_SERIAL_TC_TXBUF_SIZE * 5 + 10); count++)
+    {
+        uart_write_buffer[count] = count;
+    }
 
     rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
 

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c

@@ -92,7 +92,7 @@ static rt_bool_t uart_api()
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_TXBUF_SIZE * 5 + 1);
 
     srand(rt_tick_get());
     for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c

@@ -88,7 +88,7 @@ static rt_bool_t nonblock_write(rt_device_t uart_dev)
     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);
+        rt_thread_mdelay(10);
     }
 
     return RT_TRUE;

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c

@@ -70,7 +70,7 @@ static void uart_rec_entry(void *parameter)
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_malloc(rev_len + 1);
 
     while (1)
     {

+ 1 - 2
examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c

@@ -69,13 +69,12 @@ static void uart_rec_entry(void *parameter)
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_calloc(1, 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 *)uart_write_buffer, rev_len);

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c

@@ -83,7 +83,7 @@ static void uart_rec_entry(void *parameter)
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_calloc(1, rev_len + 1);
     rt_int32_t  cnt, i;
     rt_uint8_t  last_old_data;
     rt_bool_t   fisrt_flag         = RT_TRUE;

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c

@@ -79,7 +79,7 @@ static void uart_rec_entry(void *parameter)
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_calloc(1, rev_len + 1);
     rt_int32_t  cnt, i;
     rt_uint8_t  last_old_data;
     rt_bool_t   fisrt_flag         = RT_TRUE;

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c

@@ -89,7 +89,7 @@ static void uart_rec_entry(void *parameter)
 
     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));
+    uart_write_buffer = (rt_uint8_t *)rt_calloc(1, rev_len + 1);
     rt_int32_t  cnt, i;
     rt_uint8_t  last_old_data;
     rt_bool_t   fisrt_flag         = RT_TRUE;

+ 139 - 0
examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb.c

@@ -0,0 +1,139 @@
+/*
+ * 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 rx_timeout_test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
+{
+    rt_uint32_t readSize             = 0;
+    rt_int32_t  rx_timeout_send_size = send_size - send_size / 3;
+    rt_int32_t  rx_timeout           = rt_tick_from_millisecond(0.0868 * rx_timeout_send_size + 1);
+
+    rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
+
+    rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+    if (size != send_size)
+    {
+        LOG_E("size [%4d], send_size [%4d]", size, send_size);
+        return -RT_ERROR;
+    }
+
+    readSize = rt_device_read(&serial->parent, 0, uart_write_buffer, size);
+    if (readSize < (rx_timeout_send_size - 70) || readSize > (send_size - 80))
+    {
+        LOG_E("readSize [%4d], rx_timeout_send_size [%4d]", readSize, rx_timeout_send_size);
+        return -RT_ERROR;
+    }
+
+    rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
+    /* Waiting for rx to complete reception */
+    rt_thread_mdelay(0.0868 * (send_size / 3));
+
+    LOG_I("rx timeout send_size [%4d]", send_size);
+    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                = 2048;
+#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.");
+        return RT_FALSE;
+    }
+
+    rt_uint8_t *uart_write_buffer;
+    rt_uint32_t i;
+    uart_write_buffer = (rt_uint8_t *)rt_malloc(2048);
+
+
+    for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+    {
+        srand(rt_tick_get());
+        if (RT_EOK != rx_timeout_test_item(uart_write_buffer, 1024 + (rand() % 1024)))
+        {
+            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_timeout_rxb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* TC_UART_USING_TC */

+ 1 - 1
examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c

@@ -75,7 +75,7 @@ static void uart_rec_entry(void *parameter)
     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));
+    uart_write_buffer   = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE * 10 + 1);
 
     timeout = 100;
     rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&timeout);

+ 129 - 0
examples/utest/testcases/drivers/serial_v2/uart_timeout_txb.c

@@ -0,0 +1,129 @@
+/*
+ * 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
+#ifndef BSP_UART2_TX_USING_DMA
+
+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 tx_timeout_test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
+{
+    rt_uint32_t readSize             = 0;
+    rt_int32_t  tx_timeout_send_size = send_size - send_size / 3;
+    rt_int32_t  tx_timeout           = rt_tick_from_millisecond(0.0868 * tx_timeout_send_size + 1);
+    rt_device_control(&serial->parent, RT_SERIAL_CTRL_SET_TX_TIMEOUT, (void *)&tx_timeout);
+
+    rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
+    if (size < (tx_timeout_send_size - 70) || size > (send_size - 80))
+    {
+        LOG_E("size [%4d], send_size [%4d]", size, tx_timeout_send_size);
+        return -RT_ERROR;
+    }
+
+    rt_device_control(&serial->parent, RT_SERIAL_CTRL_TX_FLUSH, RT_NULL);
+    /* Waiting for rx to complete reception */
+    rt_thread_mdelay(0.0868 * (send_size / 3));
+
+    LOG_I("tx timeout send_size [%4d]", send_size);
+
+    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;
+
+    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(2048);
+    for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
+    {
+        srand(rt_tick_get());
+        if (RT_EOK != tx_timeout_test_item(uart_write_buffer, 1024 + (rand() % 1024)))
+        {
+            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_timeout_txb", utest_tc_init, utest_tc_cleanup, 30);
+
+#endif /* BSP_UART2_TX_USING_DMA */
+#endif /* TC_UART_USING_TC */