This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 45c38d8592bc8efd2ed2a661e204920dc4119811
Author: yinshengkai <[email protected]>
AuthorDate: Thu Feb 26 16:33:12 2026 +0800

    drivers/serial/16550: add polling mode support for serial drivers
    
    Adds CONFIG_16550_POLLING options to enable polling mode for
    transmission. This avoids TX interrupts and reduces interrupt latency
    at the cost of blocking during TX.
    
    Implements sendbuf() method for efficient buffer transmission
    in polling mode.
    
    Signed-off-by: yinshengkai <[email protected]>
    Signed-off-by: chao an <[email protected]>
---
 drivers/serial/Kconfig-16550 |  8 ++++++++
 drivers/serial/uart_16550.c  | 36 +++++++++++++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/serial/Kconfig-16550 b/drivers/serial/Kconfig-16550
index 183e9618170..dea015830b1 100644
--- a/drivers/serial/Kconfig-16550
+++ b/drivers/serial/Kconfig-16550
@@ -5,6 +5,14 @@
 
 if 16550_UART
 
+config 16550_POLLING
+       bool "Force polling mode for TX"
+       default n
+       ---help---
+               Force using polling mode for transmission. This avoids using TX 
interrupts
+               and potentially reduces interrupt latency, at the cost of 
blocking execution
+               during transmission.
+
 config 16550_SERIAL_DISABLE_REORDERING
        bool "Disable reordering of ttySx devices."
        default n
diff --git a/drivers/serial/uart_16550.c b/drivers/serial/uart_16550.c
index c7ad45f3f67..fd4557dbbcc 100644
--- a/drivers/serial/uart_16550.c
+++ b/drivers/serial/uart_16550.c
@@ -108,6 +108,8 @@ static void u16550_dmarxfree(FAR struct uart_dev_s *dev);
 static void u16550_dmarxconfig(FAR struct uart_dev_s *dev);
 #endif
 static void u16550_send(FAR struct uart_dev_s *dev, int ch);
+static ssize_t u16550_sendbuf(struct uart_dev_s *dev,
+                              const void *buffer, size_t size);
 static void u16550_txint(FAR struct uart_dev_s *dev, bool enable);
 static bool u16550_txready(FAR struct uart_dev_s *dev);
 static bool u16550_txempty(FAR struct uart_dev_s *dev);
@@ -154,6 +156,7 @@ static const struct uart_ops_s g_uart_ops =
   .txint          = u16550_txint,
   .txready        = u16550_txready,
   .txempty        = u16550_txempty,
+  .sendbuf        = u16550_sendbuf,
 };
 
 /* I/O buffers */
@@ -1568,6 +1571,26 @@ static void u16550_send(struct uart_dev_s *dev, int ch)
   u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
 }
 
+/****************************************************************************
+ * Name: u16550_sendbuf
+ *
+ * Description:
+ *   This method will send a buffer of bytes on the UART
+ *
+ ****************************************************************************/
+
+static ssize_t u16550_sendbuf(struct uart_dev_s *dev,
+                              const void *buffer, size_t size)
+{
+  for (size_t i = 0; i < size; i++)
+    {
+      while (!u16550_txready(dev));
+      u16550_send(dev, ((const unsigned char *)buffer)[i]);
+    }
+
+  return (ssize_t)size;
+}
+
 /****************************************************************************
  * Name: u16550_txint
  *
@@ -1588,9 +1611,14 @@ static void u16550_txint(struct uart_dev_s *dev, bool 
enable)
     }
 #endif
 
-  flags = enter_critical_section();
   if (enable)
     {
+#ifdef CONFIG_16550_POLLING
+      /* In polling mode, we loop until the buffer is empty */
+
+      uart_xmitchars(dev);
+#else
+      flags = enter_critical_section();
       priv->ier |= UART_IER_ETBEI;
       u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
 
@@ -1599,14 +1627,16 @@ static void u16550_txint(struct uart_dev_s *dev, bool 
enable)
        */
 
       uart_xmitchars(dev);
+      leave_critical_section(flags);
+#endif
     }
   else
     {
+      flags = enter_critical_section();
       priv->ier &= ~UART_IER_ETBEI;
       u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
+      leave_critical_section(flags);
     }
-
-  leave_critical_section(flags);
 }
 
 /****************************************************************************

Reply via email to