tty:support tty c_cc VMIN & VTIME

Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
anjiahao 2023-03-24 13:44:34 +08:00 committed by Xiang Xiao
parent e9dfa0094f
commit 0c9ca52f37
4 changed files with 63 additions and 4 deletions

View File

@ -26,8 +26,10 @@
#include <ctype.h>
#include <sys/types.h>
#include <sys/param.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
@ -1047,9 +1049,22 @@ static ssize_t uart_read(FAR struct file *filep,
*/
dev->recvwaiting = true;
ret = nxsem_wait(&dev->recvsem);
#ifdef CONFIG_SERIAL_TERMIOS
dev->minrecv = MIN(buflen - recvd, dev->minread - recvd);
if (dev->timeout)
{
ret = nxsem_tickwait(&dev->recvsem,
DSEC2TICK(dev->timeout));
}
else
#endif
{
ret = nxsem_wait(&dev->recvsem);
}
}
dev->recvwaiting = false;
leave_critical_section(flags);
/* Was a signal received while waiting for data to be
@ -1078,9 +1093,9 @@ static ssize_t uart_read(FAR struct file *filep,
*/
#ifdef CONFIG_SERIAL_REMOVABLE
recvd = dev->disconnected ? -ENOTCONN : -EINTR;
recvd = dev->disconnected ? -ENOTCONN : ret;
#else
recvd = -EINTR;
recvd = ret;
#endif
}
@ -1539,6 +1554,10 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
termiosp->c_iflag = dev->tc_iflag;
termiosp->c_oflag = dev->tc_oflag;
termiosp->c_lflag = dev->tc_lflag;
#ifdef CONFIG_SERIAL_TERMIOS
termiosp->c_cc[VTIME] = dev->timeout;
termiosp->c_cc[VMIN] = dev->minread;
#endif
ret = 0;
}
@ -1560,6 +1579,10 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
dev->tc_iflag = termiosp->c_iflag;
dev->tc_oflag = termiosp->c_oflag;
dev->tc_lflag = termiosp->c_lflag;
#ifdef CONFIG_SERIAL_TERMIOS
dev->timeout = termiosp->c_cc[VTIME];
dev->minread = termiosp->c_cc[VMIN];
#endif
ret = 0;
}
break;
@ -1813,6 +1836,11 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev)
nxsem_init(&dev->recvsem, 0, 0);
nxmutex_init(&dev->polllock);
#ifdef CONFIG_SERIAL_TERMIOS
dev->timeout = 0;
dev->minread = 1;
#endif
/* Register the serial driver */
sinfo("Registering %s\n", path);

View File

@ -336,7 +336,20 @@ void uart_recvchars_done(FAR uart_dev_t *dev)
* incoming data available.
*/
if (rxbuf->head >= rxbuf->tail)
{
nbytes = rxbuf->head - rxbuf->tail;
}
else
{
nbytes = rxbuf->size - rxbuf->tail + rxbuf->head;
}
#ifdef CONFIG_SERIAL_TERMIOS
if (nbytes >= dev->minrecv)
#else
if (nbytes)
#endif
{
uart_datareceived(dev);
}

View File

@ -222,7 +222,6 @@ void uart_recvchars(FAR uart_dev_t *dev)
/* Add the character to the buffer */
rxbuf->buffer[rxbuf->head] = ch;
nbytes++;
/* Increment the head index */
@ -238,7 +237,20 @@ void uart_recvchars(FAR uart_dev_t *dev)
* incoming data available.
*/
if (rxbuf->head >= rxbuf->tail)
{
nbytes = rxbuf->head - rxbuf->tail;
}
else
{
nbytes = rxbuf->size - rxbuf->tail + rxbuf->head;
}
#ifdef CONFIG_SERIAL_TERMIOS
if (nbytes >= dev->minrecv)
#else
if (nbytes)
#endif
{
uart_datareceived(dev);
}

View File

@ -321,6 +321,12 @@ struct uart_dev_s
* retained in the f_priv field of the 'struct file'.
*/
#ifdef CONFIG_SERIAL_TERMIOS
uint8_t minrecv; /* Minimum received bytes */
uint8_t minread; /* c_cc[VMIN] */
uint8_t timeout; /* c_cc[VTIME] */
#endif
struct pollfd *fds[CONFIG_SERIAL_NPOLLWAITERS];
};