summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyanCW <[email protected]>2025-08-16 11:51:57 +0800
committerGitHub <[email protected]>2025-08-16 11:51:57 +0800
commite0243e87c0230f2afcdce3e1070755f78dfee9c7 (patch)
treee1aff5d61d6231fee568b371fcb9a1864e93bdd8
parent329cffd77e203ab73f098188b0ec02b6ef6af0ed (diff)
[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
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c434
-rw-r--r--components/drivers/include/drivers/dev_serial_v2.h6
-rw-r--r--components/drivers/serial/dev_serial_v2.c403
-rw-r--r--examples/utest/testcases/drivers/serial_v2/posix/uart_posix_echo_block.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c1
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c47
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c50
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c48
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_get_unread_bytes_count.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c3
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb.c139
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c2
-rw-r--r--examples/utest/testcases/drivers/serial_v2/uart_timeout_txb.c129
20 files changed, 857 insertions, 423 deletions
diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c
index 179c95c368..3dc578ba7e 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_usart_v2.c
+++ b/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);
}
diff --git a/components/drivers/include/drivers/dev_serial_v2.h b/components/drivers/include/drivers/dev_serial_v2.h
index 5360b011e3..b987bc4543 100644
--- a/components/drivers/include/drivers/dev_serial_v2.h
+++ b/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
};
/**
diff --git a/components/drivers/serial/dev_serial_v2.c b/components/drivers/serial/dev_serial_v2.c
index dc09da1f69..2a526c809a 100644
--- a/components/drivers/serial/dev_serial_v2.c
+++ b/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);
@@ -1112,6 +1144,36 @@ static rt_err_t rt_serial_init(struct rt_device *dev)
}
/**
+ * @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
* @param oflag The flag of that the serial port opens.
@@ -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;
}
}
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
index 1a0a8ec1ee..bb273f1328 100644
--- 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
@@ -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;
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
index 3159f2d6cd..943b47b345 100644
--- a/examples/utest/testcases/drivers/serial_v2/posix/uart_posix_nonblock.c
+++ b/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++)
{
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 432181c031..1d2ab4e586 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_rx.c
+++ b/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));
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 a5893536ed..51eda0feb9 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_blocking_tx.c
+++ b/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;
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c
index 7411eeaa84..3d529d7f46 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_flush_rx.c
+++ b/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++)
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c
index 567fe3740a..2bc45a3250 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_flush_txb.c
+++ b/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);
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c b/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c
index aa086a8679..1fcfc2b99d 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_flush_txnb.c
+++ b/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);
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
index fc4323cc98..f63f663ad3 100644
--- 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
@@ -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++)
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 7723ef56b1..cd1297d919 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_nonblocking_tx.c
+++ b/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;
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
index 912d1ecd7c..e5a354f75a 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_overflow_rxb_txb.c
+++ b/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)
{
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 40702e8fb2..b844cc05b2 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txb.c
+++ b/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);
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 c2e6be8205..b5e4fe6e86 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxb_txnb.c
+++ b/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;
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 a1efcc7315..6dc7f68346 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txb.c
+++ b/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;
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 edc66e2be8..66c40c103d 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_rxnb_txnb.c
+++ b/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;
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb.c b/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb.c
new file mode 100644
index 0000000000..7c936bbfe8
--- /dev/null
+++ b/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 */
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
index ae42ee5d05..7defec6803 100644
--- a/examples/utest/testcases/drivers/serial_v2/uart_timeout_rxb_txb.c
+++ b/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);
diff --git a/examples/utest/testcases/drivers/serial_v2/uart_timeout_txb.c b/examples/utest/testcases/drivers/serial_v2/uart_timeout_txb.c
new file mode 100644
index 0000000000..9af3f40b3e
--- /dev/null
+++ b/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 */