upgrade rtt 5.2.2

This commit is contained in:
wmano
2025-09-03 20:50:03 +08:00
parent f6985d97c5
commit 5409d3a614
41 changed files with 1130 additions and 988 deletions
@@ -484,7 +484,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
return RT_EOK;
}
static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
{
CAN_HandleTypeDef *hcan;
hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
@@ -586,7 +586,7 @@ static rt_ssize_t _can_sendmsg(struct rt_can_device *can, const void *buf, rt_ui
}
}
static rt_ssize_t _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
{
HAL_StatusTypeDef status;
CAN_HandleTypeDef *hcan;
@@ -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);
}
+56
View File
@@ -16,19 +16,48 @@ if RT_USING_DFS
bool "Using working directory"
default y
if RT_USING_DFS_V1
config RT_USING_DFS_MNTTABLE
bool "Using mount table for file system"
default n
help
User can use mount table for automatically mount, for example:
const struct dfs_mount_tbl mount_table[] =
{
{"flash0", "/", "elm", 0, 0},
{0}
};
The mount_table must be terminated with NULL.
endif
config DFS_FD_MAX
int "The maximal number of opened files"
default 16
choice
prompt "The version of DFS"
default RT_USING_DFS_V1
default RT_USING_DFS_V2 if RT_USING_SMART
config RT_USING_DFS_V1
bool "DFS v1.0"
depends on !RT_USING_SMART
config RT_USING_DFS_V2
bool "DFS v2.0"
select RT_USING_DEVICE_OPS
endchoice
if RT_USING_DFS_V1
config DFS_FILESYSTEMS_MAX
int "The maximal number of mounted file system"
default 4
config DFS_FILESYSTEM_TYPES_MAX
int "The maximal number of file system type"
default 4
endif
config RT_USING_DFS_ELMFAT
bool "Enable elm-chan fatfs"
default n
@@ -133,6 +162,13 @@ if RT_USING_DFS
bool "Using devfs for device objects"
default y
if RT_USING_DFS_V1
config RT_USING_DFS_ISO9660
bool "Using ISO9660 filesystem"
depends on RT_USING_MEMHEAP
default n
endif
menuconfig RT_USING_DFS_ROMFS
bool "Enable ReadOnly file system on flash"
default n
@@ -159,6 +195,13 @@ endif
default n
# select PKG_USING_ZLIB
if RT_USING_DFS_V1
config RT_USING_DFS_RAMFS
bool "Enable RAM file system"
select RT_USING_MEMHEAP
default n
endif
config RT_USING_DFS_TMPFS
bool "Enable TMP file system"
default y if RT_USING_SMART
@@ -170,6 +213,19 @@ endif
default y if RT_USING_SMART
default n
if RT_USING_DFS_V1
config RT_USING_DFS_NFS
bool "Using NFS v3 client file system"
depends on RT_USING_LWIP
default n
if RT_USING_DFS_NFS
config RT_NFS_HOST_EXPORT
string "NFSv3 host export"
default "192.168.1.5:/"
endif
endif
if RT_USING_DFS_V2
config RT_USING_PAGECACHE
bool "Enable page cache"
@@ -15,7 +15,4 @@ config RT_USING_AUDIO
int "Record pipe size"
default 2048
config RT_UTEST_USING_AUDIO_DRIVER
bool "Enable rt_audio_api testcase"
default n
endif
@@ -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
};
/**
@@ -177,6 +177,7 @@ struct rt_pci_msi_desc
#define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1)
rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type);
rt_err_t rt_pci_msi_cleanup_irqs(struct rt_pci_device *pdev);
void rt_pci_msi_shutdown(struct rt_pci_device *pdev);
void rt_pci_msix_shutdown(struct rt_pci_device *pdev);
@@ -10,3 +10,5 @@ config RT_PCI_HOST_GENERIC
default y
rsource "dw/Kconfig"
osource "$(SOC_DM_PCI_DIR)/Kconfig"
@@ -204,6 +204,7 @@ void dw_pcie_free_msi(struct dw_pcie_port *port)
rt_dma_free_coherent(pci->dev, sizeof(rt_uint64_t), port->msi_data,
port->msi_data_phy);
port->msi_data = RT_NULL;
}
}
@@ -331,7 +332,8 @@ rt_err_t dw_pcie_host_init(struct dw_pcie_port *port)
{
LOG_E("Invalid count of irq = %d", port->irq_count);
return -RT_EINVAL;
err = -RT_EINVAL;
goto _err_free_cfg;
}
}
@@ -341,7 +343,8 @@ rt_err_t dw_pcie_host_init(struct dw_pcie_port *port)
if (!port->msi_pic)
{
return -RT_ENOMEM;
err = -RT_ENOMEM;
goto _err_free_cfg;
}
port->msi_pic->priv_data = port;
@@ -404,6 +407,13 @@ _err_free_bridge:
rt_pci_host_bridge_free(bridge);
port->bridge = RT_NULL;
_err_free_cfg:
if (port->cfg0_base)
{
rt_iounmap(port->cfg0_base);
port->cfg0_base = RT_NULL;
}
return err;
}
@@ -144,3 +144,42 @@ rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type)
return err;
}
rt_err_t rt_pci_msi_cleanup_irqs(struct rt_pci_device *pdev)
{
int type;
struct rt_pic *msi_pic;
struct rt_pci_msi_desc *desc;
if (!pdev)
{
return -RT_EINVAL;
}
msi_pic = pdev->msi_pic;
if (!msi_pic)
{
return -RT_EINVAL;
}
desc = rt_pci_msi_first_desc(pdev);
type = desc->is_msix ? PCIY_MSIX : PCIY_MSI;
if (type == PCIY_MSI)
{
for (int idx = 0; idx < desc->vector_used; ++idx)
{
msi_pic->ops->irq_free_msi(msi_pic, desc->irq + idx);
}
}
else if (type == PCIY_MSIX)
{
rt_pci_msi_for_each_desc(pdev, desc)
{
msi_pic->ops->irq_free_msi(msi_pic, desc->irq);
}
}
return RT_EOK;
}
@@ -233,6 +233,8 @@ void rt_pci_msi_free_irqs(struct rt_pci_device *pdev)
pdev->msix_base = RT_NULL;
}
rt_pci_msi_cleanup_irqs(pdev);
rt_pci_msi_for_each_desc(pdev, desc)
{
/* To safety */
+5 -2
View File
@@ -284,7 +284,7 @@ rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
phy_addr_cells, phy_size_cells, cpu_addr_cells,
&host_bridge->dma_regions, &host_bridge->dma_regions_nr);
if (err != -RT_EEMPTY)
if (err && err != -RT_EEMPTY)
{
rt_free(host_bridge->bus_regions);
host_bridge->bus_regions_nr = 0;
@@ -314,7 +314,10 @@ rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
if (rt_ofw_prop_read_u32_array_index(dev_np, "bus-range", 0, 2, host_bridge->bus_range) < 0)
{
return -RT_EIO;
host_bridge->bus_range[0] = 0x00;
host_bridge->bus_range[1] = 0xff;
LOG_I("%s: No \"%s\" found, using [%#02x, %#02x]", rt_ofw_node_full_name(dev_np), "bus-range",
host_bridge->bus_range[0], host_bridge->bus_range[1]);
}
propname = rt_ofw_get_prop_fuzzy_name(dev_np, ",pci-domain$");
@@ -1463,9 +1463,8 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
/* if the next position is read index, discard this 'read char' */
if (rx_fifo->put_index == rx_fifo->get_index)
{
rx_fifo->get_index += 1;
rx_fifo->get_index = rx_fifo->put_index;
rx_fifo->is_full = RT_TRUE;
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
_serial_check_buffer_size();
}
@@ -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;
if (tx_timeout == RT_WAITING_NO)
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_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)
delta_tick = rt_tick_get_delta(begin_tick);
if (delta_tick >= base_tx_timeout)
{
return -RT_ETIMEOUT;
}
else
{
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;
}
}
@@ -255,7 +255,7 @@ _fail:
static rt_err_t pwm_fan_cool_remove(struct rt_platform_device *pdev)
{
struct pwm_fan_cool *pf_cool = pdev->parent.ofw_node;
struct pwm_fan_cool *pf_cool = pdev->parent.user_data;
rt_thermal_cooling_device_unregister(&pf_cool->parent);
@@ -223,6 +223,7 @@ _scan_cooling:
}
}
_end:
;
}
#else
rt_inline void thermal_ofw_setup(struct rt_ofw_node *np, struct rt_thermal_zone_device *zdev)
+19 -4
View File
@@ -165,6 +165,7 @@ long list_thread(void)
rt_list_t *next = (rt_list_t *)RT_NULL;
const char *item_title = "thread";
const size_t tcb_strlen = sizeof(void *) * 2 + 2;
const size_t usage_strlen = sizeof(void *) + 1;
int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
@@ -173,18 +174,22 @@ long list_thread(void)
maxlen = RT_NAME_MAX;
#ifdef RT_USING_SMP
rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title);
rt_kprintf("%-*.*s cpu bind pri status sp stack size max used left tick error tcb addr usage\n", maxlen, maxlen, item_title);
object_split(maxlen);
rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- -------");
rt_kprintf(" ");
object_split(tcb_strlen);
rt_kprintf(" ");
object_split(usage_strlen);
rt_kprintf("\n");
#else
rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr\n", maxlen, maxlen, item_title);
rt_kprintf("%-*.*s pri status sp stack size max used left tick error tcb addr usage\n", maxlen, maxlen, item_title);
object_split(maxlen);
rt_kprintf(" --- ------- ---------- ---------- ------ ---------- -------");
rt_kprintf(" ");
object_split(tcb_strlen);
rt_kprintf(" ");
object_split(usage_strlen);
rt_kprintf("\n");
#endif /*RT_USING_SMP*/
@@ -243,17 +248,22 @@ long list_thread(void)
ptr = (rt_uint8_t *)thread->stack_addr + thread->stack_size - 1;
while (*ptr == '#')ptr --;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n",
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p",
((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
thread->stack_size,
((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
thread->remaining_tick,
rt_strerror(thread->error),
thread);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
#else
rt_kprintf(" N/A\n");
#endif
#else
ptr = (rt_uint8_t *)thread->stack_addr;
while (*ptr == '#') ptr ++;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p\n",
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %s %p",
thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
thread->stack_size,
(thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
@@ -261,6 +271,11 @@ long list_thread(void)
RT_SCHED_PRIV(thread).remaining_tick,
rt_strerror(thread->error),
thread);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_kprintf(" %3d%%\n", rt_thread_get_usage(thread));
#else
rt_kprintf(" N/A\n");
#endif
#endif
}
}
+4 -6
View File
@@ -169,14 +169,10 @@ struct at_client
/* The maximum supported receive data length */
rt_size_t recv_bufsz;
#if (!defined(RT_USING_SERIAL_V2))
rt_sem_t rx_notice;
#endif
rt_mutex_t lock;
struct rt_event event;
struct rt_mutex lock;
at_response_t resp;
rt_sem_t resp_notice;
at_resp_status_t resp_status;
struct at_urc_table *urc_table;
@@ -184,6 +180,7 @@ struct at_client
const struct at_urc *urc;
rt_thread_t parser;
rt_slist_t list;
};
typedef struct at_client *at_client_t;
#endif /* AT_USING_CLIENT */
@@ -207,6 +204,7 @@ int at_req_parse_args(const char *req_args, const char *req_expr, ...);
/* AT client initialize and start*/
int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bufsz);
int at_client_deInit(const char *dev_name);
/* ========================== multiple AT client function ============================ */
+252 -265
View File
@@ -12,6 +12,7 @@
* 2021-07-14 Sszl fix a buf of leaking memory
* 2025-01-02 dongly support SERIAL_V2
* 2025-04-18 RyanCw support New SERIAL_V2
* 2025-08-11 RyanCw add client deInit
*/
#include <at.h>
@@ -19,19 +20,24 @@
#include <stdlib.h>
#include <string.h>
#define LOG_TAG "at.clnt"
#define LOG_TAG "at.clnt"
#include <at_log.h>
#ifdef AT_USING_CLIENT
#define AT_RESP_END_OK "OK"
#define AT_RESP_END_ERROR "ERROR"
#define AT_RESP_END_FAIL "FAIL"
#define AT_END_CR_LF "\r\n"
#define AT_END_CR "\r"
#define AT_END_LF "\n"
#define AT_END_RAW ""
#define AT_RESP_END_OK "OK"
#define AT_RESP_END_ERROR "ERROR"
#define AT_RESP_END_FAIL "FAIL"
#define AT_END_CR_LF "\r\n"
#define AT_END_CR "\r"
#define AT_END_LF "\n"
#define AT_END_RAW ""
static struct at_client at_client_table[AT_CLIENT_NUM_MAX] = { 0 };
#define at_client_rx_notice_event (1 << 0)
#define at_client_resp_notice_event (1 << 1)
#define at_client_deInit_event (1 << 2)
#define at_client_deInit_over_event (1 << 3)
static rt_slist_t g_at_client_list = RT_SLIST_OBJECT_INIT(g_at_client_list);
extern rt_size_t at_utils_send(rt_device_t dev,
rt_off_t pos,
@@ -41,7 +47,7 @@ extern rt_size_t at_vprintfln(rt_device_t device, char *send_buf, rt_size_t buf_
extern rt_size_t at_vprintf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
extern rt_size_t at_vprintfcr(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
extern rt_size_t at_vprintflf(rt_device_t device, char *send_buf, rt_size_t buf_size, const char *format, va_list args);
extern void at_print_raw_cmd(const char *type, const char *cmd, rt_size_t size);
extern void at_print_raw_cmd(const char *type, const char *cmd, rt_size_t size);
/**
* Create response object.
@@ -59,14 +65,14 @@ at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t
{
at_response_t resp = RT_NULL;
resp = (at_response_t) rt_calloc(1, sizeof(struct at_response));
resp = (at_response_t)rt_calloc(1, sizeof(struct at_response));
if (resp == RT_NULL)
{
LOG_E("AT create response object failed! No memory for response object!");
return RT_NULL;
}
resp->buf = (char *) rt_calloc(1, buf_size);
resp->buf = (char *)rt_calloc(1, buf_size);
if (resp->buf == RT_NULL)
{
LOG_E("AT create response object failed! No memory for response buffer!");
@@ -74,10 +80,10 @@ at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t
return RT_NULL;
}
resp->buf_size = buf_size;
resp->line_num = line_num;
resp->buf_size = buf_size;
resp->line_num = line_num;
resp->line_counts = 0;
resp->timeout = timeout;
resp->timeout = timeout;
return resp;
}
@@ -123,7 +129,7 @@ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t
{
resp->buf_size = buf_size;
p_temp = (char *) rt_realloc(resp->buf, buf_size);
p_temp = (char *)rt_realloc(resp->buf, buf_size);
if (p_temp == RT_NULL)
{
LOG_D("No memory for realloc response buffer size(%d).", buf_size);
@@ -136,7 +142,7 @@ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t
}
resp->line_num = line_num;
resp->timeout = timeout;
resp->timeout = timeout;
return resp;
}
@@ -152,7 +158,7 @@ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t
*/
const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line)
{
char *resp_buf = resp->buf;
char *resp_buf = resp->buf;
rt_size_t line_num = 1;
RT_ASSERT(resp);
@@ -187,7 +193,7 @@ const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line)
*/
const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword)
{
char *resp_buf = resp->buf;
char *resp_buf = resp->buf;
rt_size_t line_num = 1;
RT_ASSERT(resp);
@@ -219,8 +225,8 @@ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword)
*/
int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char *resp_expr, ...)
{
va_list args;
int resp_args_num = 0;
va_list args;
int resp_args_num = 0;
const char *resp_line_buf = RT_NULL;
RT_ASSERT(resp);
@@ -254,8 +260,8 @@ int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char
*/
int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const char *resp_expr, ...)
{
va_list args;
int resp_args_num = 0;
va_list args;
int resp_args_num = 0;
const char *resp_line_buf = RT_NULL;
RT_ASSERT(resp);
@@ -290,7 +296,7 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const
*/
int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...)
{
va_list args;
va_list args;
rt_err_t result = RT_EOK;
RT_ASSERT(cmd_expr);
@@ -307,18 +313,18 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
return -RT_EBUSY;
}
rt_mutex_take(client->lock, RT_WAITING_FOREVER);
rt_mutex_take(&client->lock, RT_WAITING_FOREVER);
client->resp_status = AT_RESP_OK;
if (resp != RT_NULL)
{
resp->buf_len = 0;
resp->buf_len = 0;
resp->line_counts = 0;
}
client->resp = resp;
rt_sem_control(client->resp_notice, RT_IPC_CMD_RESET, RT_NULL);
rt_event_recv(&client->event, at_client_resp_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, 0, NULL);
va_start(args, cmd_expr);
client->last_cmd_len = at_vprintfln(client->device, client->send_buf, client->send_bufsz, cmd_expr, args);
@@ -330,11 +336,11 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
if (resp != RT_NULL)
{
if (rt_sem_take(client->resp_notice, resp->timeout) != RT_EOK)
if (rt_event_recv(&client->event, at_client_resp_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, resp->timeout, NULL) != RT_EOK)
{
LOG_W("execute command (%.*s) timeout (%d ticks)!", client->last_cmd_len, client->send_buf, resp->timeout);
client->resp_status = AT_RESP_TIMEOUT;
result = -RT_ETIMEOUT;
result = -RT_ETIMEOUT;
}
else if (client->resp_status != AT_RESP_OK)
{
@@ -345,7 +351,7 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
client->resp = RT_NULL;
rt_mutex_release(client->lock);
rt_mutex_release(&client->lock);
return result;
}
@@ -366,9 +372,9 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
* -2 : wait timeout
* -7 : enter AT CLI mode
*/
int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* format, const char *cmd_expr, ...)
int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char *format, const char *cmd_expr, ...)
{
va_list args;
va_list args;
rt_err_t result = RT_EOK;
RT_ASSERT(cmd_expr);
@@ -385,18 +391,18 @@ int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* f
return -RT_EBUSY;
}
rt_mutex_take(client->lock, RT_WAITING_FOREVER);
rt_mutex_take(&client->lock, RT_WAITING_FOREVER);
client->resp_status = AT_RESP_OK;
if (resp != RT_NULL)
{
resp->buf_len = 0;
resp->buf_len = 0;
resp->line_counts = 0;
}
client->resp = resp;
rt_sem_control(client->resp_notice, RT_IPC_CMD_RESET, RT_NULL);
rt_event_recv(&client->event, at_client_resp_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, 0, NULL);
va_start(args, cmd_expr);
@@ -421,11 +427,11 @@ int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* f
if (resp != RT_NULL)
{
if (rt_sem_take(client->resp_notice, resp->timeout) != RT_EOK)
if (rt_event_recv(&client->event, at_client_resp_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, resp->timeout, NULL) != RT_EOK)
{
LOG_W("execute command (%.*s) timeout (%d ticks)!", client->last_cmd_len, client->send_buf, resp->timeout);
client->resp_status = AT_RESP_TIMEOUT;
result = -RT_ETIMEOUT;
result = -RT_ETIMEOUT;
}
else if (client->resp_status != AT_RESP_OK)
{
@@ -436,7 +442,7 @@ int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* f
client->resp = RT_NULL;
rt_mutex_release(client->lock);
rt_mutex_release(&client->lock);
return result;
}
@@ -453,10 +459,9 @@ int at_obj_exec_cmd_format(at_client_t client, at_response_t resp, const char* f
*/
int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout)
{
rt_err_t result = RT_EOK;
at_response_t resp = RT_NULL;
rt_tick_t start_time = 0;
char *client_name = client->device->parent.name;
rt_err_t result = RT_EOK;
at_response_t resp = RT_NULL;
rt_tick_t start_time = 0;
if (client == RT_NULL)
{
@@ -467,14 +472,10 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout)
resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
if (resp == RT_NULL)
{
LOG_E("no memory for AT client(%s) response object.", client_name);
LOG_E("no memory for AT client(%s) response object.", client->device->parent.name);
return -RT_ENOMEM;
}
rt_mutex_take(client->lock, RT_WAITING_FOREVER);
client->resp = resp;
rt_sem_control(client->resp_notice, RT_IPC_CMD_RESET, RT_NULL);
start_time = rt_tick_get();
while (1)
@@ -482,26 +483,18 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout)
/* Check whether it is timeout */
if (rt_tick_get() - start_time > rt_tick_from_millisecond(timeout))
{
LOG_E("wait AT client(%s) connect timeout(%d tick).", client_name, timeout);
LOG_E("wait AT client(%s) connect timeout(%d tick).", client->device->parent.name, timeout);
result = -RT_ETIMEOUT;
break;
}
/* Check whether it is already connected */
resp->buf_len = 0;
resp->line_counts = 0;
at_utils_send(client->device, 0, "AT\r\n", 4);
if (rt_sem_take(client->resp_notice, resp->timeout) == RT_EOK)
if (at_obj_exec_cmd(client, resp, "AT") == RT_EOK)
{
break;
}
}
at_delete_resp(resp);
client->resp = RT_NULL;
rt_mutex_release(client->lock);
return result;
}
@@ -531,45 +524,15 @@ rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size
at_print_raw_cmd("sendline", buf, size);
#endif
rt_mutex_take(client->lock, RT_WAITING_FOREVER);
rt_mutex_take(&client->lock, RT_WAITING_FOREVER);
len = at_utils_send(client->device, 0, buf, size);
rt_mutex_release(client->lock);
rt_mutex_release(&client->lock);
return len;
}
static rt_err_t at_client_getchar(at_client_t client, char *ch, rt_int32_t timeout)
{
rt_err_t result = RT_EOK;
#if (!defined(RT_USING_SERIAL_V2))
while (rt_device_read(client->device, 0, ch, 1) == 0)
{
result = rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout));
if (result != RT_EOK)
{
return result;
}
rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL);
}
#else
rt_int32_t rx_timeout = rt_tick_from_millisecond(timeout);
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
result = rt_device_read(client->device, 0, ch, 1);
if(result <= 0)
{
result = -RT_ERROR;
}
rx_timeout = RT_WAITING_FOREVER;
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout);
#endif
return result;
}
/**
* AT client receive fixed-length data.
*
@@ -595,31 +558,31 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_i
return 0;
}
#if (!defined(RT_USING_SERIAL_V2))
#ifndef RT_USING_SERIAL_V2
while (size)
{
rt_size_t read_len;
rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL);
rt_event_recv(&client->event, at_client_rx_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, 0, NULL);
read_len = rt_device_read(client->device, 0, buf + read_idx, size);
if (read_len > 0)
{
read_idx += read_len;
size -= read_len;
size -= read_len;
}
else
{
if (rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)) != RT_EOK)
if (rt_event_recv(&client->event, at_client_rx_notice_event, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, rt_tick_from_millisecond(timeout), NULL) != RT_EOK)
break;
}
}
#else
rt_int32_t rx_timeout = rt_tick_from_millisecond(timeout);
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
read_idx = rt_device_read(client->device, 0, buf, size);
rx_timeout = RT_WAITING_FOREVER;
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void*)&rx_timeout);
read_idx = rt_device_read(client->device, 0, buf, size);
rx_timeout = RT_WAITING_NO;
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
#endif
#ifdef AT_PRINT_RAW_CMD
@@ -671,13 +634,13 @@ int at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt_
if (client->urc_table_size == 0)
{
client->urc_table = (struct at_urc_table *) rt_calloc(1, sizeof(struct at_urc_table));
client->urc_table = (struct at_urc_table *)rt_calloc(1, sizeof(struct at_urc_table));
if (client->urc_table == RT_NULL)
{
return -RT_ENOMEM;
}
client->urc_table[0].urc = urc_table;
client->urc_table[0].urc = urc_table;
client->urc_table[0].urc_size = table_sz;
client->urc_table_size++;
}
@@ -686,16 +649,15 @@ int at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt_
struct at_urc_table *new_urc_table = RT_NULL;
/* realloc urc table space */
new_urc_table = (struct at_urc_table *) rt_realloc(client->urc_table,client->urc_table_size * sizeof(struct at_urc_table) + sizeof(struct at_urc_table));
new_urc_table = (struct at_urc_table *)rt_realloc(client->urc_table, client->urc_table_size * sizeof(struct at_urc_table) + sizeof(struct at_urc_table));
if (new_urc_table == RT_NULL)
{
return -RT_ENOMEM;
}
client->urc_table = new_urc_table;
client->urc_table[client->urc_table_size].urc = urc_table;
client->urc_table = new_urc_table;
client->urc_table[client->urc_table_size].urc = urc_table;
client->urc_table[client->urc_table_size].urc_size = table_sz;
client->urc_table_size++;
}
return RT_EOK;
@@ -710,18 +672,22 @@ int at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt_
*/
at_client_t at_client_get(const char *dev_name)
{
int idx = 0;
RT_ASSERT(dev_name);
for (idx = 0; idx < AT_CLIENT_NUM_MAX; idx++)
rt_slist_t *node;
at_client_t client;
rt_base_t level = rt_hw_interrupt_disable();
rt_slist_for_each(node, &g_at_client_list)
{
if (at_client_table[idx].device &&
(rt_strcmp(at_client_table[idx].device->parent.name, dev_name) == 0))
client = rt_slist_entry(node, struct at_client, list);
if (rt_strcmp(client->device->parent.name, dev_name) == 0)
{
return &at_client_table[idx];
rt_hw_interrupt_enable(level);
return client;
}
}
rt_hw_interrupt_enable(level);
return RT_NULL;
}
@@ -733,20 +699,24 @@ at_client_t at_client_get(const char *dev_name)
*/
at_client_t at_client_get_first(void)
{
if (at_client_table[0].device == RT_NULL)
{
return RT_NULL;
}
at_client_t client = RT_NULL;
return &at_client_table[0];
rt_base_t level = rt_hw_interrupt_disable();
if (!rt_slist_isempty(&g_at_client_list))
{
client = rt_slist_first_entry(&g_at_client_list, struct at_client, list);
}
rt_hw_interrupt_enable(level);
return client;
}
static const struct at_urc *get_urc_obj(at_client_t client)
{
rt_size_t i, j, prefix_len, suffix_len;
rt_size_t bufsz;
char *buffer = RT_NULL;
const struct at_urc *urc = RT_NULL;
rt_size_t i, j, prefix_len, suffix_len;
rt_size_t bufsz;
char *buffer = RT_NULL;
const struct at_urc *urc = RT_NULL;
struct at_urc_table *urc_table = RT_NULL;
if (client->urc_table == RT_NULL)
@@ -755,14 +725,14 @@ static const struct at_urc *get_urc_obj(at_client_t client)
}
buffer = client->recv_line_buf;
bufsz = client->recv_line_len;
bufsz = client->recv_line_len;
for (i = 0; i < client->urc_table_size; i++)
{
for (j = 0; j < client->urc_table[i].urc_size; j++)
{
urc_table = client->urc_table + i;
urc = urc_table->urc + j;
urc = urc_table->urc + j;
prefix_len = rt_strlen(urc->cmd_prefix);
suffix_len = rt_strlen(urc->cmd_suffix);
@@ -771,7 +741,7 @@ static const struct at_urc *get_urc_obj(at_client_t client)
continue;
}
if ((prefix_len ? !rt_strncmp(buffer, urc->cmd_prefix, prefix_len) : 1)
&& (suffix_len ? !rt_strncmp(buffer + bufsz - suffix_len, urc->cmd_suffix, suffix_len) : 1))
&& (suffix_len ? !rt_strncmp(buffer + bufsz - suffix_len, urc->cmd_suffix, suffix_len) : 1))
{
return urc;
}
@@ -781,44 +751,85 @@ static const struct at_urc *get_urc_obj(at_client_t client)
return RT_NULL;
}
static rt_err_t at_client_getchar(at_client_t client, char *ch)
{
rt_err_t result = RT_EOK;
rt_ssize_t recvLen = 0;
/* Temporarily retain the distinction */
#ifndef RT_USING_SERIAL_V2
recvLen = rt_device_read(client->device, 0, ch, 1);
if (recvLen <= 0)
{
result = -RT_ERROR;
}
#else
recvLen = rt_device_read(client->device, 0, ch, 1);
if (recvLen != 1)
{
result = -RT_ERROR;
}
#endif
return result;
}
static int at_recv_readline(at_client_t client)
{
char ch = 0, last_ch = 0;
rt_bool_t is_full = RT_FALSE;
char ch = 0, last_ch = 0;
rt_bool_t is_full = RT_FALSE;
rt_uint32_t event;
rt_memset(client->recv_line_buf, 0x00, client->recv_bufsz);
client->recv_line_len = 0;
while (1)
{
at_client_getchar(client, &ch, RT_WAITING_FOREVER);
event = 0;
rt_event_recv(&client->event, at_client_rx_notice_event | at_client_deInit_event,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &event);
if (client->recv_line_len < client->recv_bufsz)
if (event & at_client_deInit_event)
{
client->recv_line_buf[client->recv_line_len++] = ch;
}
else
{
is_full = RT_TRUE;
rt_event_send(&client->event, at_client_deInit_over_event);
rt_thread_delete(rt_thread_self());
}
/* is newline or URC data */
client->urc = get_urc_obj(client);
if (client->urc != RT_NULL || (ch == '\n' && last_ch == '\r')
|| (client->end_sign != 0 && ch == client->end_sign))
if (event & at_client_rx_notice_event)
{
if (is_full)
while (RT_EOK == at_client_getchar(client, &ch))
{
LOG_E("read line failed. The line data length is out of buffer size(%d)!", client->recv_bufsz);
rt_memset(client->recv_line_buf, 0x00, client->recv_bufsz);
client->recv_line_len = 0;
return -RT_EFULL;
if (client->recv_line_len < client->recv_bufsz)
{
client->recv_line_buf[client->recv_line_len++] = ch;
}
else
{
is_full = RT_TRUE;
}
/* is newline or URC data */
client->urc = get_urc_obj(client);
if (client->urc != RT_NULL || (ch == '\n' && last_ch == '\r')
|| (client->end_sign != 0 && ch == client->end_sign))
{
if (is_full)
{
LOG_E("read line failed. The line data length is out of buffer size(%d)!", client->recv_bufsz);
rt_memset(client->recv_line_buf, 0x00, client->recv_bufsz);
client->recv_line_len = 0;
return -RT_EFULL;
}
/* Since the buffer state is uncertain, we proactively clear it; the overhead is negligible. */
rt_event_send(&client->event, at_client_rx_notice_event);
goto __next;
}
last_ch = ch;
}
break;
}
last_ch = ch;
}
__next:
#ifdef AT_PRINT_RAW_CMD
at_print_raw_cmd("recvline", client->recv_line_buf, client->recv_line_len);
#endif
@@ -828,7 +839,7 @@ static int at_recv_readline(at_client_t client)
static void client_parser(at_client_t client)
{
while(1)
while (1)
{
if (at_recv_readline(client) > 0)
{
@@ -870,13 +881,13 @@ static void client_parser(at_client_t client)
client->resp_status = AT_RESP_OK;
}
else if (rt_memcmp(client->recv_line_buf, AT_RESP_END_OK, rt_strlen(AT_RESP_END_OK)) == 0
&& resp->line_num == 0)
&& resp->line_num == 0)
{
/* get the end data by response result, return response state END_OK. */
client->resp_status = AT_RESP_OK;
}
else if (rt_strstr(client->recv_line_buf, AT_RESP_END_ERROR)
|| (rt_memcmp(client->recv_line_buf, AT_RESP_END_FAIL, rt_strlen(AT_RESP_END_FAIL)) == 0))
|| (rt_memcmp(client->recv_line_buf, AT_RESP_END_FAIL, rt_strlen(AT_RESP_END_FAIL)) == 0))
{
client->resp_status = AT_RESP_ERROR;
}
@@ -891,146 +902,76 @@ static void client_parser(at_client_t client)
}
client->resp = RT_NULL;
rt_sem_release(client->resp_notice);
rt_event_send(&client->event, at_client_resp_notice_event);
}
else
{
/* log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);*/
LOG_D("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);
}
}
}
}
#if (!defined(RT_USING_SERIAL_V2))
static rt_err_t at_client_rx_ind(rt_device_t dev, rt_size_t size)
{
int idx = 0;
rt_slist_t *node;
at_client_t client;
for (idx = 0; idx < AT_CLIENT_NUM_MAX; idx++)
if (size <= 0)
{
if (at_client_table[idx].device == dev && size > 0)
return RT_EOK;
}
rt_base_t level = rt_hw_interrupt_disable();
rt_slist_for_each(node, &g_at_client_list)
{
client = rt_slist_entry(node, struct at_client, list);
if (client->device == dev)
{
rt_sem_release(at_client_table[idx].rx_notice);
rt_event_send(&client->event, at_client_rx_notice_event);
break;
}
}
rt_hw_interrupt_enable(level);
return RT_EOK;
}
#endif
/* initialize the client object parameters */
static int at_client_para_init(at_client_t client)
{
#define AT_CLIENT_LOCK_NAME "at_c"
#define AT_CLIENT_SEM_NAME "at_cs"
#define AT_CLIENT_RESP_NAME "at_cr"
#define AT_CLIENT_THREAD_NAME "at_clnt"
#define AT_CLIENT_LOCK_NAME "at_c"
#define AT_CLIENT_EVENT_NAME "at_ce"
#define AT_CLIENT_THREAD_NAME "at_clnt"
int result = RT_EOK;
static int at_client_num = 0;
int result = RT_EOK;
char name[RT_NAME_MAX];
client->status = AT_STATUS_UNINITIALIZED;
rt_base_t level = rt_hw_interrupt_disable();
unsigned int at_client_num = rt_slist_len(&g_at_client_list);
rt_hw_interrupt_enable(level);
client->recv_line_len = 0;
client->recv_line_buf = (char *) rt_calloc(1, client->recv_bufsz);
if (client->recv_line_buf == RT_NULL)
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_THREAD_NAME, at_client_num);
client->parser = rt_thread_create(name,
(void (*)(void *parameter))client_parser,
client,
1024 + 512,
RT_THREAD_PRIORITY_MAX / 3 - 1,
5);
if (client->parser == RT_NULL)
{
LOG_E("AT client initialize failed! No memory for receive buffer.");
result = -RT_ENOMEM;
goto __exit;
}
client->last_cmd_len = 0;
client->send_buf = (char *) rt_calloc(1, client->send_bufsz);
if (client->send_buf == RT_NULL)
{
LOG_E("AT client initialize failed! No memory for send buffer.");
result = -RT_ENOMEM;
goto __exit;
}
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_LOCK_NAME, at_client_num);
client->lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO);
if (client->lock == RT_NULL)
{
LOG_E("AT client initialize failed! at_client_recv_lock create failed!");
result = -RT_ENOMEM;
goto __exit;
}
rt_mutex_init(&client->lock, name, RT_IPC_FLAG_PRIO);
#if (!defined(RT_USING_SERIAL_V2))
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_SEM_NAME, at_client_num);
client->rx_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
if (client->rx_notice == RT_NULL)
{
LOG_E("AT client initialize failed! at_client_notice semaphore create failed!");
result = -RT_ENOMEM;
goto __exit;
}
#endif
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_RESP_NAME, at_client_num);
client->resp_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO);
if (client->resp_notice == RT_NULL)
{
LOG_E("AT client initialize failed! at_client_resp semaphore create failed!");
result = -RT_ENOMEM;
goto __exit;
}
client->urc_table = RT_NULL;
client->urc_table_size = 0;
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_THREAD_NAME, at_client_num);
client->parser = rt_thread_create(name,
(void (*)(void *parameter))client_parser,
client,
1024 + 512,
RT_THREAD_PRIORITY_MAX / 3 - 1,
5);
if (client->parser == RT_NULL)
{
result = -RT_ENOMEM;
}
rt_snprintf(name, RT_NAME_MAX, "%s%d", AT_CLIENT_EVENT_NAME, at_client_num);
rt_event_init(&client->event, name, RT_IPC_FLAG_FIFO);
__exit:
if (result != RT_EOK)
{
if (client->lock)
{
rt_mutex_delete(client->lock);
}
#if (!defined(RT_USING_SERIAL_V2))
if (client->rx_notice)
{
rt_sem_delete(client->rx_notice);
}
#endif
if (client->resp_notice)
{
rt_sem_delete(client->resp_notice);
}
if (client->recv_line_buf)
{
rt_free(client->recv_line_buf);
}
if (client->send_buf)
{
rt_free(client->send_buf);
}
rt_memset(client, 0x00, sizeof(struct at_client));
}
else
{
at_client_num++;
}
return result;
}
@@ -1047,10 +988,9 @@ __exit:
*/
int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bufsz)
{
int idx = 0;
int result = RT_EOK;
rt_err_t open_result = RT_EOK;
at_client_t client = RT_NULL;
int result = RT_EOK;
rt_err_t open_result = RT_EOK;
at_client_t client = RT_NULL;
RT_ASSERT(dev_name);
RT_ASSERT(recv_bufsz > 0);
@@ -1061,18 +1001,20 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
return result;
}
for (idx = 0; idx < AT_CLIENT_NUM_MAX && at_client_table[idx].device; idx++);
if (idx >= AT_CLIENT_NUM_MAX)
client = rt_malloc(sizeof(struct at_client) + recv_bufsz + send_bufsz);
if (client == RT_NULL)
{
LOG_E("AT client initialize failed! Check the maximum number(%d) of AT client.", AT_CLIENT_NUM_MAX);
result = -RT_EFULL;
result = -RT_ENOMEM;
goto __exit;
}
rt_memset(client, 0, sizeof(struct at_client) + recv_bufsz + send_bufsz);
client->status = AT_STATUS_UNINITIALIZED;
client->recv_bufsz = recv_bufsz;
client->recv_line_buf = ((char *)client) + sizeof(struct at_client);
client = &at_client_table[idx];
client->recv_bufsz = recv_bufsz;
client->send_bufsz = send_bufsz;
client->send_buf = ((char *)client) + sizeof(struct at_client) + client->recv_bufsz;
result = at_client_para_init(client);
if (result != RT_EOK)
@@ -1085,8 +1027,7 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
if (client->device)
{
RT_ASSERT(client->device->type == RT_Device_Class_Char);
#if (!defined(RT_USING_SERIAL_V2))
rt_device_set_rx_indicate(client->device, at_client_rx_ind);
#ifndef RT_USING_SERIAL_V2
/* using DMA mode first */
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
/* using interrupt mode when DMA mode not supported */
@@ -1098,6 +1039,8 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
#else
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
RT_ASSERT(open_result == RT_EOK);
rt_int32_t rx_timeout = RT_WAITING_NO;
rt_device_control(client->device, RT_SERIAL_CTRL_SET_RX_TIMEOUT, (void *)&rx_timeout);
#endif
}
else
@@ -1109,17 +1052,61 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
__exit:
if (result == RT_EOK)
{
client->status = AT_STATUS_INITIALIZED;
rt_slist_init(&client->list);
rt_base_t level = rt_hw_interrupt_disable();
rt_slist_append(&g_at_client_list, &client->list);
rt_hw_interrupt_enable(level);
rt_device_set_rx_indicate(client->device, at_client_rx_ind);
client->status = AT_STATUS_INITIALIZED;
rt_thread_startup(client->parser);
LOG_I("AT client(V%s) on device %s initialize success.", AT_SW_VERSION, dev_name);
}
else
{
if (RT_NULL != client->parser)
{
rt_thread_delete(client->parser);
}
if (RT_NULL != client)
{
rt_free(client);
}
LOG_E("AT client(V%s) on device %s initialize failed(%d).", AT_SW_VERSION, dev_name, result);
}
return result;
}
#endif /* AT_USING_CLIENT */
int at_client_deInit(const char *dev_name)
{
int result = RT_EOK;
at_client_t client = RT_NULL;
RT_ASSERT(dev_name);
client = at_client_get(dev_name);
if (client == RT_NULL)
{
return RT_EOK;
}
rt_base_t level = rt_hw_interrupt_disable();
rt_slist_remove(&g_at_client_list, &client->list);
rt_hw_interrupt_enable(level);
rt_event_send(&client->event, at_client_deInit_event);
rt_event_recv(&client->event, at_client_deInit_over_event, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, NULL);
rt_event_detach(&client->event);
rt_mutex_detach(&client->lock);
result = rt_device_close(client->device);
rt_free(client);
return result;
}
#endif /* AT_USING_CLIENT */
+1 -1
View File
@@ -8,7 +8,7 @@ menuconfig RT_USING_LWIP
if RT_USING_LWIP
config RT_USING_LWIP_LOCAL_VERSION
bool "Use LwIP local version only"
default y
default n
help
If don't select this option, both local version and upstream
version can be selected. If select this option, only local version
+1 -1
View File
@@ -83,7 +83,7 @@ extern "C" {
/* RT-Thread version information */
#define RT_VERSION_MAJOR 5 /**< Major version number (X.x.x) */
#define RT_VERSION_MINOR 2 /**< Minor version number (x.X.x) */
#define RT_VERSION_PATCH 1 /**< Patch version number (x.x.X) */
#define RT_VERSION_PATCH 2 /**< Patch version number (x.x.X) */
/* e.g. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0) */
#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000U) + (minor * 100U) + revise)
+3
View File
@@ -181,6 +181,9 @@ rt_err_t rt_thread_wakeup(rt_thread_t thread);
void rt_thread_wakeup_set(struct rt_thread *thread, rt_wakeup_func_t func, void* user_data);
#endif /* RT_USING_SMART */
rt_err_t rt_thread_get_name(rt_thread_t thread, char *name, rt_uint8_t name_size);
#ifdef RT_USING_CPU_USAGE_TRACER
rt_uint8_t rt_thread_get_usage(rt_thread_t thread);
#endif /* RT_USING_CPU_USAGE_TRACER */
#ifdef RT_USING_SIGNALS
void rt_thread_alloc_sig(rt_thread_t tid);
void rt_thread_free_sig(rt_thread_t tid);
+15 -2
View File
@@ -238,10 +238,23 @@ HardFault_Handler:
MRS r0, psp /* get fault context from thread. */
_get_sp_done:
STMFD r0!, {r4 - r11} /* push r4 - r11 register */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
STMFD r0!, {lr} /* push dummy for flag */
TST lr, #0x10 /* if(!EXC_RETURN[4]) */
IT EQ
VSTMDBEQ r0!, {d8 - d15} /* push FPU register s16~s31 */
#endif
STMFD r0!, {r4 - r11} /* push r4 - r11 register */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
MOV r4, #0x00 /* flag = 0 */
TST lr, #0x10 /* if(!EXC_RETURN[4]) */
IT EQ
MOVEQ r4, #0x01 /* flag = 1 */
STMFD r0!, {r4} /* push flag */
#endif
STMFD r0!, {lr} /* push exec_return register */
TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+19 -5
View File
@@ -237,14 +237,28 @@ HardFault_Handler:
MRS r0, psp ; get fault context from thread.
_get_sp_done
STMFD r0!, {r4 - r11} ; push r4 - r11 register
;STMFD r0!, {lr} ; push exec_return register
#if defined ( __ARMVFP__ )
SUB r0, r0, #0x04 ; push dummy for flag
STR lr, [r0]
TST lr, #0x10 ; if(!EXC_RETURN[4])
BNE skip_push_fpu
VSTMDB r0!, {d8 - d15} ; push FPU register s16~s31
skip_push_fpu
#endif
STMFD r0!, {r4 - r11} ; push r4 - r11 register
#if defined ( __ARMVFP__ )
MOV r4, #0x00 ; flag = 0
TST lr, #0x10 ; if(!EXC_RETURN[4])
BNE push_flag
MOV r4, #0x01 ; flag = 1
push_flag
SUB r0, r0, #0x04
STR lr, [r0]
STR r4, [r0] ; push flag
#endif
SUB r0, r0, #0x04
STR lr, [r0] ; push exec_return register
TST lr, #0x04 ; if(!EXC_RETURN[2])
BEQ _update_msp
+13 -2
View File
@@ -236,10 +236,21 @@ HardFault_Handler PROC
MRSEQ r0, msp ; [2]=0 ==> Z=1, get fault context from handler.
MRSNE r0, psp ; [2]=1 ==> Z=0, get fault context from thread.
STMFD r0!, {r4 - r11} ; push r4 - r11 register
IF {FPU} != "SoftVFP"
STMFD r0!, {lr} ; push dummy for flag
TST lr, #0x10 ; if(!EXC_RETURN[4])
VSTMFDEQ r0!, {d8 - d15} ; push FPU register s16~s31
ENDIF
STMFD r0!, {r4 - r11} ; push r4 - r11 register
IF {FPU} != "SoftVFP"
MOV r4, #0x00 ; flag = 0
TST lr, #0x10 ; if(!EXC_RETURN[4])
MOVEQ r4, #0x01 ; flag = 1
STMFD r0!, {r4} ; push flag
ENDIF
STMFD r0!, {lr} ; push exec_return register
TST lr, #0x04 ; if(!EXC_RETURN[2])
+5 -3
View File
@@ -192,10 +192,12 @@ endif
config RT_USING_CPU_USAGE_TRACER
select RT_USING_HOOK
bool "Enable cpu usage tracing"
help
Enable cpu usage tracer for application like top.
default y if RT_USING_SMART
default n
help
Enable thread CPU usage statistics and monitoring.
This feature tracks CPU usage for each thread and provides
percentage information through the list thread command.
It will automatically integrate with the scheduler to track thread execution time.
menu "kservice options"
config RT_USING_TINY_FFS
+4
View File
@@ -59,6 +59,8 @@ RTM_EXPORT(rt_spin_lock)
/**
* @brief This function will unlock the spinlock, will unlock the thread scheduler.
*
* @note If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @param lock is a pointer to the spinlock.
*/
void rt_spin_unlock(struct rt_spinlock *lock)
@@ -95,6 +97,8 @@ RTM_EXPORT(rt_spin_lock_irqsave)
/**
* @brief This function will unlock the spinlock and then restore current cpu interrupt status, will unlock the thread scheduler.
*
* @note If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @param lock is a pointer to the spinlock.
*
* @param level is interrupt status returned by rt_spin_lock_irqsave().
+4 -2
View File
@@ -40,7 +40,8 @@ void rt_spin_lock(struct rt_spinlock *lock)
/**
* @brief This function will unlock the spinlock, will unlock the thread scheduler.
* If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @note If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @param lock is a pointer to the spinlock.
*/
@@ -73,7 +74,8 @@ rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
/**
* @brief This function will unlock the spinlock and then restore current cpu interrupt status, will unlock the thread scheduler.
* If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @note If the scheduling function is called before unlocking, it will be scheduled in this function.
*
* @param lock is a pointer to the spinlock.
*
-5
View File
@@ -250,9 +250,4 @@ menu "klibc options"
default n
endmenu # rt_strnlen options
config RT_UTEST_TC_USING_KLIBC
bool "Enable klibc utest cases"
select RT_USING_UTEST
default n
endmenu
+4
View File
@@ -0,0 +1,4 @@
config RT_UTEST_TC_USING_KLIBC
bool "Enable klibc utest cases"
select RT_USING_UTEST
default n
+47
View File
@@ -539,6 +539,53 @@ rt_err_t rt_backtrace_thread(rt_thread_t thread)
return rc;
}
#ifdef RT_USING_CPU_USAGE_TRACER
/**
* @brief Get thread usage percentage relative to total system CPU time
*
* This function calculates the CPU usage percentage of a specific thread
* relative to the total CPU time consumed by all threads in the system.
*
* @param thread Pointer to the thread object. Must not be NULL.
*
* @return The CPU usage percentage as an integer value (0-100).
* Returns 0 if total system time is 0 or if CPU usage tracing is not enabled.
*
* @note This function requires RT_USING_CPU_USAGE_TRACER to be enabled.
* @note The percentage is calculated as: (thread_time * 100) / total_system_time
* @note Due to integer arithmetic, the result is truncated and may not sum
* to exactly 100% across all threads due to rounding.
* @note If thread is NULL, an assertion will be triggered in debug builds.
*/
rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
{
rt_ubase_t thread_time;
rt_ubase_t total_time = 0U;
int i;
rt_cpu_t pcpu;
RT_ASSERT(thread != RT_NULL);
thread_time = thread->user_time + thread->system_time;
/* Calculate total system time by summing all CPUs' time */
for (i = 0; i < RT_CPUS_NR; i++)
{
pcpu = rt_cpu_index(i);
total_time += pcpu->cpu_stat.user + pcpu->cpu_stat.system + pcpu->cpu_stat.idle;
}
if (total_time > 0U)
{
/* Calculate thread usage percentage: (thread_time * 100) / total_time */
rt_ubase_t usage = (thread_time * 100U) / total_time;
return (rt_uint8_t)(usage > 100U ? 100U : usage);
}
return 0U;
}
#endif /* RT_USING_CPU_USAGE_TRACER */
#if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
#include <stdlib.h> /* for string service */
+1 -1
View File
@@ -516,7 +516,7 @@ rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
obj_name_len = rt_strlen(name);
if(obj_name_len > RT_NAME_MAX - 1)
{
LOG_E("Object name '%s' exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX);
LOG_E("Object name %s exceeds RT_NAME_MAX=%d, consider increasing RT_NAME_MAX.", name, RT_NAME_MAX);
RT_ASSERT(obj_name_len <= RT_NAME_MAX - 1);
}
rt_memcpy(object->name, name, obj_name_len);
+4 -16
View File
@@ -31,6 +31,7 @@
* 2023-03-27 rose_man Split into scheduler upc and scheduler_mp.c
* 2023-10-17 ChuShicheng Modify the timing of clearing RT_THREAD_STAT_YIELD flag bits
* 2025-08-04 Pillar Add rt_scheduler_critical_switch_flag
* 2025-08-20 RyanCW rt_scheduler_lock_nest use atomic operations
*/
#define __RT_IPC_SOURCE__
@@ -49,7 +50,7 @@ rt_uint8_t rt_thread_ready_table[32];
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
extern volatile rt_atomic_t rt_interrupt_nest;
static rt_int16_t rt_scheduler_lock_nest;
static rt_atomic_t rt_scheduler_lock_nest;
rt_uint8_t rt_current_priority;
static rt_int8_t rt_scheduler_critical_switch_flag;
@@ -649,22 +650,9 @@ RTM_EXPORT(rt_exit_critical_safe);
*/
rt_base_t rt_enter_critical(void)
{
rt_base_t level;
rt_base_t critical_level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
/*
* the maximal number of nest is RT_UINT16_MAX, which is big
* enough and does not check here
*/
rt_scheduler_lock_nest ++;
critical_level = rt_scheduler_lock_nest;
/* enable interrupt */
rt_hw_interrupt_enable(level);
critical_level = rt_atomic_add(&rt_scheduler_lock_nest, 1) + 1;
return critical_level;
}
RTM_EXPORT(rt_enter_critical);
@@ -722,7 +710,7 @@ RTM_EXPORT(rt_exit_critical);
*/
rt_uint16_t rt_critical_level(void)
{
return rt_scheduler_lock_nest;
return (rt_uint16_t)rt_atomic_load(&rt_scheduler_lock_nest);
}
RTM_EXPORT(rt_critical_level);
+7 -6
View File
@@ -8,6 +8,7 @@
# Change Logs:
# Date Author Notes
# 2024-08-27 Supperthomas the first version
# 2025-08-09 ThearchyHelios Fix Darwin detection and URL
#
#这个脚本用于安装RT-Thread开发环境 请确保网络畅通
@@ -58,7 +59,7 @@ detect_os() {
if [ -f "/etc/os-release" ]; then
OS="Linux"
elif [ -f "/System/Library/CoreServices/SystemVersion.plist" ]; then
OS="macOS"
OS="Darwin"
elif [[ -d "/mnt/c/Windows" || -d "/c/Windows" ]]; then
OS="WSL"
else
@@ -91,7 +92,7 @@ install_on_ubuntu() {
# 根据检测结果决定是否使用--gitee参数
if [ "$use_gitee" = true ]; then
wget https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh
wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_ubuntu.sh
chmod 777 install_ubuntu.sh
echo "Installing on China gitee..."
./install_ubuntu.sh --gitee
@@ -124,7 +125,7 @@ install_on_macos() {
# 根据检测结果决定是否使用--gitee参数
if [ "$use_gitee" = true ]; then
wget https://raw.githubusercontent.com/RT-Thread/env/master/install_macos.sh
wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_macos.sh
chmod 777 install_macos.sh
echo "Installing on China gitee..."
./install_macos.sh --gitee
@@ -147,7 +148,7 @@ install_on_windows() {
# 根据检测结果决定是否使用--gitee参数
if [ "$use_gitee" = true ]; then
wget https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1
wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_windows.ps1
echo "Installing on China gitee..."
./install_windows.ps1 --gitee
else
@@ -162,7 +163,7 @@ install_on_opensuse() {
echo "Installing on openSUSE..."
use_gitee=$(check_if_china_ip)
if [ "$use_gitee" = true ]; then
wget https://raw.githubusercontent.com/RT-Thread/env/master/install_suse.sh
wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_suse.sh
chmod 777 install_suse.sh
echo "Installing on China gitee..."
./install_suse.sh --gitee
@@ -198,7 +199,7 @@ main() {
;;
esac
;;
macOS)
Darwin)
install_on_macos
;;
WSL)
+2 -2
View File
@@ -327,7 +327,7 @@ def get_file_md5(file):
# Exclude utestcases
def exclude_utestcases(RTT_ROOT):
if os.path.isfile(os.path.join(RTT_ROOT, 'examples/utest/testcases/Kconfig')):
if os.path.isfile(os.path.join(RTT_ROOT, 'Kconfig.utestcases')):
return
if not os.path.isfile(os.path.join(RTT_ROOT, 'Kconfig')):
@@ -337,7 +337,7 @@ def exclude_utestcases(RTT_ROOT):
data = f.readlines()
with open(os.path.join(RTT_ROOT, 'Kconfig'), 'w') as f:
for line in data:
if line.find('examples/utest/testcases/Kconfig') == -1:
if line.find('Kconfig.utestcases') == -1:
f.write(line)
+1 -1
View File
@@ -118,7 +118,7 @@ def bsp_update_kconfig_testcases(dist_dir):
data = f.readlines()
with open(os.path.join(dist_dir, 'rt-thread/Kconfig'), 'w') as f:
for line in data:
if line.find('examples/utest/testcases/Kconfig') == -1:
if line.find('Kconfig.utestcases') == -1:
f.write(line)
def bsp_update_kconfig(dist_dir):
+4 -1
View File
@@ -114,6 +114,9 @@ def _CDKProject(tree, target, script):
Define = tree.find('BuildConfigs/BuildConfig/Compiler/Define')
Define.text = '; '.join(set(CPPDEFINES))
Define = tree.find('BuildConfigs/BuildConfig/Asm/Define')
Define.text = '; '.join(set(CPPDEFINES))
CC_Misc = tree.find('BuildConfigs/BuildConfig/Compiler/OtherFlags')
CC_Misc.text = CCFLAGS
@@ -128,7 +131,7 @@ def _CDKProject(tree, target, script):
LibName.text=';'.join(LIBS)
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.write(etree.tostring(root, encoding='utf-8').decode('utf-8'))
out.close()
def CDKProject(target, script):