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 179c95c3683..3dc578ba7e0 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 -#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 5360b011e3b..b987bc45434 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 dc09da1f698..2a526c809a0 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); @@ -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; } } diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 61c91954154..25e12c9a902 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -24,6 +24,7 @@ #ifdef RT_USING_FINSH +#include #include "shell.h" #include "msh.h" @@ -177,7 +178,8 @@ int finsh_getchar(void) { return -1; /* EOF */ } - +/* Temporarily retain the distinction */ +#ifndef RT_USING_SERIAL_V2 while (rt_device_read(device, -1, &ch, 1) != 1) { rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER); @@ -190,6 +192,19 @@ int finsh_getchar(void) } } } +#else + while (rt_device_read(device, -1, &ch, 1) != 1) + { + if (shell->device != device) + { + device = shell->device; + if (device == RT_NULL) + { + return -1; + } + } + } +#endif return ch; #endif /* RT_USING_POSIX_STDIO */ #else @@ -199,6 +214,7 @@ int finsh_getchar(void) } #if !defined(RT_USING_POSIX_STDIO) && defined(RT_USING_DEVICE) +#ifndef RT_USING_SERIAL_V2 static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size) { RT_ASSERT(shell != RT_NULL); @@ -208,6 +224,7 @@ static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size) return RT_EOK; } +#endif /** * @ingroup group_finsh @@ -231,8 +248,13 @@ void finsh_set_device(const char *device_name) /* check whether it's a same device */ if (dev == shell->device) return; /* open this device and set the new device in finsh shell */ +#ifndef RT_USING_SERIAL_V2 if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | \ RT_DEVICE_FLAG_STREAM) == RT_EOK) +#else + if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_BLOCKING | \ + RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_STREAM) == RT_EOK) +#endif { if (shell->device != RT_NULL) { @@ -246,7 +268,12 @@ void finsh_set_device(const char *device_name) shell->line_curpos = shell->line_position = 0; shell->device = dev; +#ifndef RT_USING_SERIAL_V2 rt_device_set_rx_indicate(dev, finsh_rx_ind); +#else + rt_int32_t rx_timeout = RT_WAITING_FOREVER; + rt_device_control(dev, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout); +#endif } } @@ -924,7 +951,10 @@ int finsh_system_init(void) FINSH_THREAD_PRIORITY, 10); #endif /* RT_USING_HEAP */ +#ifndef RT_USING_SERIAL_V2 rt_sem_init(&(shell->rx_sem), "shrx", 0, 0); +#endif + finsh_set_prompt_mode(1); if (tid != NULL && result == RT_EOK) diff --git a/components/finsh/shell.h b/components/finsh/shell.h index db4a77d5566..a6b2df9eada 100644 --- a/components/finsh/shell.h +++ b/components/finsh/shell.h @@ -60,7 +60,9 @@ enum input_stat }; struct finsh_shell { +#ifndef RT_USING_SERIAL_V2 struct rt_semaphore rx_sem; +#endif enum input_stat stat; 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 1a0a8ec1eec..bb273f13283 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 3159f2d6cd9..943b47b345a 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 432181c0318..1d2ab4e586b 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 a5893536ed4..51eda0feb92 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 7411eeaa84a..3d529d7f46d 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 567fe3740aa..2bc45a32506 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 aa086a8679e..1fcfc2b99d5 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 fc4323cc98d..f63f663ad36 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 7723ef56b14..cd1297d9198 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 912d1ecd7cb..e5a354f75a8 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 40702e8fb24..b844cc05b27 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 c2e6be82058..b5e4fe6e862 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 a1efcc73157..6dc7f683463 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 edc66e2be85..66c40c103d9 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 00000000000..7c936bbfe8b --- /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 +#include "utest.h" +#include +#include + + +#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 ae42ee5d05a..7defec68034 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 00000000000..9af3f40b3ea --- /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 +#include "utest.h" +#include +#include + +#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 */