This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6173b0ecbf9cedd2db42619ca8961f42c75c427a Author: chao an <[email protected]> AuthorDate: Tue Oct 27 13:41:37 2026 +0800 drivers/serial: Copy RX buffers in chunks Add a fast path in uart_readv() for raw input where no newline, carriage return, canonical, or echo processing is enabled. The raw path copies each contiguous segment from the UART RX ring into the uio buffer with uio_copyfrom() instead of consuming one byte at a time. The existing per-byte path is kept for termios translation, canonical editing, and echo handling. Signed-off-by: chao an <[email protected]> --- drivers/serial/serial.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index ad1ee3a102f..d8743938160 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1015,12 +1015,13 @@ static ssize_t uart_readv(FAR struct file *filep, FAR struct uio *uio) #ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS unsigned int nbuffered; unsigned int watermark; - sbuf_size_t head; #endif irqstate_t flags; ssize_t recvd = 0; ssize_t buflen; bool echoed = false; + bool rawmode; + sbuf_size_t head; sbuf_size_t tail; char ch; int ret; @@ -1044,6 +1045,9 @@ static ssize_t uart_readv(FAR struct file *filep, FAR struct uio *uio) */ buflen = uio->uio_resid; + rawmode = (dev->tc_iflag & (INLCR | IGNCR | ICRNL)) == 0 && + (dev->tc_lflag & (ICANON | ECHO)) == 0; + while (recvd < buflen) { #ifdef CONFIG_SERIAL_REMOVABLE @@ -1078,8 +1082,40 @@ static ssize_t uart_readv(FAR struct file *filep, FAR struct uio *uio) */ tail = rxbuf->tail; - if (rxbuf->head != tail) + head = rxbuf->head; + if (head != tail) { + if (rawmode) + { + ssize_t ncopy; + + if (head > tail) + { + ncopy = head - tail; + } + else + { + ncopy = rxbuf->size - tail; + } + + if (ncopy > buflen - recvd) + { + ncopy = buflen - recvd; + } + + uio_copyfrom(uio, recvd, &rxbuf->buffer[tail], ncopy); + recvd += ncopy; + + tail += ncopy; + if (tail >= rxbuf->size) + { + tail = 0; + } + + rxbuf->tail = tail; + continue; + } + /* Take the next character from the tail of the buffer */ ch = rxbuf->buffer[tail];
