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 1522959a5012ee06a2b4e020b115203a1bb4f3b7 Author: chao an <[email protected]> AuthorDate: Tue Oct 27 12:27:01 2026 +0800 drivers/usbhost: Copy serial RX buffers in chunks Replace the byte-at-a-time copies from USB bulk IN packets to the UART RX rings in the CDC ACM and FT232R host drivers with memcpy() over each contiguous ring segment. The receive workers still preserve the one-empty-slot ring-buffer rule and keep the existing USB packet accounting, FT232R status-byte offset, and uart_datareceived() notifications. This reduces per-byte loop overhead when larger USB serial packets are received. Signed-off-by: chao an <[email protected]> --- drivers/usbhost/usbhost_cdcacm.c | 73 +++++++++++++++++---------------------- drivers/usbhost/usbhost_ft232r.c | 74 +++++++++++++++++----------------------- 2 files changed, 64 insertions(+), 83 deletions(-) diff --git a/drivers/usbhost/usbhost_cdcacm.c b/drivers/usbhost/usbhost_cdcacm.c index 8e48d0911b1..21047c3a8a0 100644 --- a/drivers/usbhost/usbhost_cdcacm.c +++ b/drivers/usbhost/usbhost_cdcacm.c @@ -1061,7 +1061,6 @@ static void usbhost_rxdata_work(FAR void *arg) FAR struct uart_buffer_s *rxbuf; ssize_t nread; int nxfrd; - int nexthead; int rxndx; int ret; @@ -1081,17 +1080,6 @@ static void usbhost_rxdata_work(FAR void *arg) rxndx = priv->rxndx; nxfrd = 0; - /* Get the index to the value of the UART RX buffer head AFTER the - * first character has been stored. We need to know this in order - * to test if the UART RX buffer is full. - */ - - nexthead = rxbuf->head + 1; - if (nexthead >= rxbuf->size) - { - nexthead = 0; - } - /* Loop until either: * * 1. The UART RX buffer is full @@ -1105,17 +1093,6 @@ static void usbhost_rxdata_work(FAR void *arg) while (priv->rxena && !priv->disconnected) #endif { - /* Stop now if there is no room for another - * character in the RX buffer. - */ - - if (nexthead == rxbuf->tail) - { - /* Break out of the loop, rescheduling the work */ - - break; - } - /* Do we have any buffer RX data to transfer? */ if (priv->nrxbytes < 1) @@ -1156,32 +1133,46 @@ static void usbhost_rxdata_work(FAR void *arg) } } - /* Transfer one byte from the RX packet buffer into UART RX buffer */ - - rxbuf->buffer[rxbuf->head] = priv->inbuf[rxndx]; - nxfrd++; + /* Transfer one contiguous block from the RX packet buffer into the + * UART RX circular buffer, leaving one byte free to distinguish full + * from empty. + */ - /* Save the updated indices */ + if (rxbuf->head >= rxbuf->tail) + { + ret = rxbuf->size - rxbuf->head; + if (rxbuf->tail == 0) + { + ret--; + } + } + else + { + ret = rxbuf->tail - rxbuf->head - 1; + } - rxbuf->head = nexthead; - priv->rxndx = rxndx; + if (ret <= 0) + { + break; + } - /* Update the head point for for the next pass through the loop - * handling. If nexthead incremented to rxbuf->tail, then the - * RX buffer will and we will exit the loop at the top. - */ + if (ret > priv->nrxbytes - rxndx) + { + ret = priv->nrxbytes - rxndx; + } - if (++nexthead >= rxbuf->size) + memcpy(&rxbuf->buffer[rxbuf->head], &priv->inbuf[rxndx], ret); + rxbuf->head += ret; + if (rxbuf->head >= rxbuf->size) { - nexthead = 0; + rxbuf->head = 0; } - /* Increment the index in the USB IN packet buffer. If the - * index becomes equal to the number of bytes in the buffer, then - * we have consumed all of the RX data. - */ + rxndx += ret; + nxfrd += ret; + priv->rxndx = rxndx; - if (++rxndx >= priv->nrxbytes) + if (rxndx >= priv->nrxbytes) { /* In that case set the number of bytes in the buffer to zero. * This will force re-reading on the next time through the loop. diff --git a/drivers/usbhost/usbhost_ft232r.c b/drivers/usbhost/usbhost_ft232r.c index be0c7d7a06d..890595dd274 100644 --- a/drivers/usbhost/usbhost_ft232r.c +++ b/drivers/usbhost/usbhost_ft232r.c @@ -1143,7 +1143,6 @@ static void usbhost_rxdata_work(FAR void *arg) FAR struct uart_buffer_s *rxbuf; ssize_t nread; int nxfrd; - int nexthead; int rxndx; int ret; @@ -1163,17 +1162,6 @@ static void usbhost_rxdata_work(FAR void *arg) rxndx = priv->rxndx; nxfrd = 0; - /* Get the index to the value of the UART RX buffer head AFTER the - * first character has been stored. We need to know this in order - * to test if the UART RX buffer is full. - */ - - nexthead = rxbuf->head + 1; - if (nexthead >= rxbuf->size) - { - nexthead = 0; - } - /* Loop until either: * * 1. The UART RX buffer is full @@ -1187,17 +1175,6 @@ static void usbhost_rxdata_work(FAR void *arg) while (priv->rxena && !priv->disconnected) #endif { - /* Stop now if there is no room for another - * character in the RX buffer. - */ - - if (nexthead == rxbuf->tail) - { - /* Break out of the loop, rescheduling the work */ - - break; - } - /* Do we have any buffer RX data to transfer? */ if (priv->nrxbytes < 1) @@ -1250,34 +1227,47 @@ static void usbhost_rxdata_work(FAR void *arg) } } - /* Transfer one byte from the RX packet buffer into UART RX buffer. - * +2 to account for the two status byes + /* Transfer one contiguous block from the RX packet buffer into the + * UART RX circular buffer, leaving one byte free to distinguish full + * from empty. Add two to the packet index to skip the FTDI status + * bytes. */ - rxbuf->buffer[rxbuf->head] = priv->inbuf[rxndx + 2]; - nxfrd++; - - /* Save the updated indices */ + if (rxbuf->head >= rxbuf->tail) + { + ret = rxbuf->size - rxbuf->head; + if (rxbuf->tail == 0) + { + ret--; + } + } + else + { + ret = rxbuf->tail - rxbuf->head - 1; + } - rxbuf->head = nexthead; - priv->rxndx = rxndx; + if (ret <= 0) + { + break; + } - /* Update the head point for for the next pass through the loop - * handling. If nexthead incremented to rxbuf->tail, then the - * RX buffer will and we will exit the loop at the top. - */ + if (ret > priv->nrxbytes - rxndx) + { + ret = priv->nrxbytes - rxndx; + } - if (++nexthead >= rxbuf->size) + memcpy(&rxbuf->buffer[rxbuf->head], &priv->inbuf[rxndx + 2], ret); + rxbuf->head += ret; + if (rxbuf->head >= rxbuf->size) { - nexthead = 0; + rxbuf->head = 0; } - /* Increment the index in the USB IN packet buffer. If the - * index becomes equal to the number of bytes in the buffer, then - * we have consumed all of the RX data. - */ + rxndx += ret; + nxfrd += ret; + priv->rxndx = rxndx; - if (++rxndx >= priv->nrxbytes) + if (rxndx >= priv->nrxbytes) { /* In that case set the number of bytes in the buffer to zero. * This will force re-reading on the next time through the loop.
