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
+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