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


The following commit(s) were added to refs/heads/master by this push:
     new 673b4245f77 xtensa/esp32s3: Fix CONSOLE_DEV clobbered by USBSERIAL 
macro.
673b4245f77 is described below

commit 673b4245f77ba995f25e1b958720e6d12f59b1bd
Author: Felipe Moura <[email protected]>
AuthorDate: Thu Sep 3 12:15:17 2026 -0300

    xtensa/esp32s3: Fix CONSOLE_DEV clobbered by USBSERIAL macro.
    
    When a real UART (CONFIG_UARTx_SERIAL_CONSOLE) is selected as the
    system console while CONFIG_ESP32S3_USBSERIAL is also enabled (e.g. to
    keep /dev/ttyACM0 available as a secondary device alongside an
    external console UART), the unconditional
    
      #ifdef CONFIG_ESP32S3_USBSERIAL
      #  define CONSOLE_DEV g_uart_usbserial
      #endif
    
    block silently redefines CONSOLE_DEV, clobbering the correct earlier
    definition that pointed it at the chosen UART device.
    
    Confirmed on real hardware (Seeed XIAO ESP32-S3): with UART0 selected
    as console and USBSERIAL also enabled, the board boot-looped on
    RTCWDT_RTC_RST every ~8s, never reaching NSH. With this fix, NSH comes
    up normally over UART0 and /dev/ttyACM0 remains available.
    
    Signed-off-by: Felipe Moura <[email protected]>
    Assisted-by: Claude:claude-sonnet-5
---
 arch/xtensa/src/esp32s3/esp32s3_serial.c | 284 ++++++++++++++++---------------
 1 file changed, 145 insertions(+), 139 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/esp32s3_serial.c 
b/arch/xtensa/src/esp32s3/esp32s3_serial.c
index 11d4b3f71c1..33d23f2251e 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_serial.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_serial.c
@@ -101,8 +101,11 @@
 #  endif
 #endif /* CONSOLE_UART */
 
-#ifdef CONFIG_ESP32S3_USBSERIAL
+#if defined(CONFIG_ESP32S3_USBSERIAL) && !defined(CONSOLE_DEV)
 #  define CONSOLE_DEV           g_uart_usbserial
+#endif
+
+#ifdef CONFIG_ESP32S3_USBSERIAL
 #  define TTYACM0_DEV           g_uart_usbserial
 #endif
 
@@ -855,194 +858,196 @@ static int esp32s3_ioctl(struct file *filep, int cmd, 
unsigned long arg)
     {
 #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
 
-    /* Get the internal driver data structure for debug purposes. */
-
-    case TIOCSERGSTRUCT:
-      {
-         struct esp32s3_uart_s *user = (struct esp32s3_uart_s *)arg;
-         if (user == NULL)
-           {
-             ret = -EINVAL;
-           }
-         else
-           {
-             memcpy(user, dev->priv, sizeof(struct esp32s3_uart_s));
-           }
-       }
-       break;
+      /* Get the internal driver data structure for debug purposes. */
+
+      case TIOCSERGSTRUCT:
+        {
+          struct esp32s3_uart_s *user = (struct esp32s3_uart_s *)arg;
+
+          if (user == NULL)
+            {
+              ret = -EINVAL;
+            }
+          else
+            {
+              memcpy(user, dev->priv, sizeof(struct esp32s3_uart_s));
+            }
+        }
+        break;
 #endif
 
 #ifdef CONFIG_SERIAL_TERMIOS
 
-    /* Fill a termios structure with the required information. */
+      /* Fill a termios structure with the required information. */
+
+      case TCGETS:
+        {
+          struct termios  *termiosp   = (struct termios *)arg;
+          struct esp32s3_uart_s *priv = (struct esp32s3_uart_s *)dev->priv;
 
-    case TCGETS:
-      {
-        struct termios  *termiosp   = (struct termios *)arg;
-        struct esp32s3_uart_s *priv = (struct esp32s3_uart_s *)dev->priv;
-        if (termiosp == NULL)
-          {
-            ret = -EINVAL;
-            break;
-          }
+          if (termiosp == NULL)
+            {
+              ret = -EINVAL;
+              break;
+            }
 
-        /* Return parity (0 = no parity, 1 = odd parity, 2 = even parity). */
+          /* Return parity (0 = no, 1 = odd, 2 = even). */
 
-        termiosp->c_cflag = (priv->parity != 0 ? PARENB : 0) |
-                            (priv->parity == 1 ? PARODD : 0);
+          termiosp->c_cflag = (priv->parity != 0 ? PARENB : 0) |
+                              (priv->parity == 1 ? PARODD : 0);
 
-        /* Return stop bits */
+          /* Return stop bits */
 
-        termiosp->c_cflag |= priv->stop_b2 != 0 ? CSTOPB : 0;
+          termiosp->c_cflag |= priv->stop_b2 != 0 ? CSTOPB : 0;
 
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
-        termiosp->c_cflag |=  priv->oflow != 0 ? CCTS_OFLOW : 0;
+          termiosp->c_cflag |=  priv->oflow != 0 ? CCTS_OFLOW : 0;
 #endif
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
-        termiosp->c_cflag |=  priv->iflow != 0 ? CRTS_IFLOW : 0;
+          termiosp->c_cflag |=  priv->iflow != 0 ? CRTS_IFLOW : 0;
 #endif
 
-        /* Set the baud rate in the termiosp using the
-         * cfsetispeed interface.
-         */
-
-        cfsetispeed(termiosp, priv->baud);
-
-        /* Return number of bits. */
-
-        switch (priv->bits)
-          {
-          case 5:
-            termiosp->c_cflag |= CS5;
-            break;
-
-          case 6:
-            termiosp->c_cflag |= CS6;
-            break;
-
-          case 7:
-            termiosp->c_cflag |= CS7;
-            break;
-
-          default:
-          case 8:
-            termiosp->c_cflag |= CS8;
-            break;
-          }
-      }
-      break;
-
-    case TCSETS:
-      {
-        struct termios  *termiosp   = (struct termios *)arg;
-        struct esp32s3_uart_s *priv = (struct esp32s3_uart_s *)dev->priv;
-        uint32_t baud;
-        uint32_t current_int_sts;
-        uint8_t  parity;
-        uint8_t  bits;
-        uint8_t  stop2;
+          /* Set the baud rate in the termiosp using the
+           * cfsetispeed interface.
+           */
+
+          cfsetispeed(termiosp, priv->baud);
+
+          /* Return number of bits. */
+
+          switch (priv->bits)
+            {
+              case 5:
+                termiosp->c_cflag |= CS5;
+                break;
+
+              case 6:
+                termiosp->c_cflag |= CS6;
+                break;
+
+              case 7:
+                termiosp->c_cflag |= CS7;
+                break;
+
+              default:
+              case 8:
+                termiosp->c_cflag |= CS8;
+                break;
+            }
+        }
+        break;
+
+      case TCSETS:
+        {
+          struct termios  *termiosp   = (struct termios *)arg;
+          struct esp32s3_uart_s *priv = (struct esp32s3_uart_s *)dev->priv;
+          uint32_t baud;
+          uint32_t current_int_sts;
+          uint8_t  parity;
+          uint8_t  bits;
+          uint8_t  stop2;
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
-        bool iflow;
+          bool iflow;
 #endif
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
-        bool oflow;
+          bool oflow;
 #endif
 
-        if (termiosp == NULL)
-          {
-            ret = -EINVAL;
-            break;
-          }
+          if (termiosp == NULL)
+            {
+              ret = -EINVAL;
+              break;
+            }
 
-        /* Get the target baud rate to change. */
+          /* Get the target baud rate to change. */
 
-        baud = cfgetispeed(termiosp);
+          baud = cfgetispeed(termiosp);
 
-        /* Decode number of bits. */
+          /* Decode number of bits. */
 
-        switch (termiosp->c_cflag & CSIZE)
-          {
-          case CS5:
-            bits = 5;
-            break;
+          switch (termiosp->c_cflag & CSIZE)
+            {
+              case CS5:
+                bits = 5;
+                break;
 
-          case CS6:
-            bits = 6;
-            break;
+              case CS6:
+                bits = 6;
+                break;
 
-          case CS7:
-            bits = 7;
-            break;
+              case CS7:
+                bits = 7;
+                break;
 
-          case CS8:
-            bits = 8;
-            break;
+              case CS8:
+                bits = 8;
+                break;
 
-          default:
-            ret = -EINVAL;
-            break;
-          }
+              default:
+                ret = -EINVAL;
+                break;
+            }
 
-        /* Decode parity. */
+          /* Decode parity. */
 
-        if ((termiosp->c_cflag & PARENB) != 0)
-          {
-            parity = (termiosp->c_cflag & PARODD) != 0 ? 1 : 2;
-          }
-        else
-          {
-            parity = 0;
-          }
+          if ((termiosp->c_cflag & PARENB) != 0)
+            {
+              parity = (termiosp->c_cflag & PARODD) != 0 ? 1 : 2;
+            }
+          else
+            {
+              parity = 0;
+            }
 
-        /* Decode stop bits. */
+          /* Decode stop bits. */
 
-        stop2 = (termiosp->c_cflag & CSTOPB) != 0 ? 1 : 0;
+          stop2 = (termiosp->c_cflag & CSTOPB) != 0 ? 1 : 0;
 
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
-        iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;
+          iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;
 #endif
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
-        oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
+          oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
 #endif
 
-        /* Verify that all settings are valid before
-         * performing the changes.
-         */
+          /* Verify that all settings are valid before
+           * performing the changes.
+           */
 
-        if (ret == OK)
-          {
-            /* Fill the private struct fields. */
+          if (ret == OK)
+            {
+              /* Fill the private struct fields. */
 
-            priv->baud      = baud;
-            priv->parity    = parity;
-            priv->bits      = bits;
-            priv->stop_b2   = stop2;
+              priv->baud      = baud;
+              priv->parity    = parity;
+              priv->bits      = bits;
+              priv->stop_b2   = stop2;
 #ifdef CONFIG_SERIAL_IFLOWCONTROL
-            priv->iflow     = iflow;
+              priv->iflow     = iflow;
 #endif
 #ifdef CONFIG_SERIAL_OFLOWCONTROL
-            priv->oflow     = oflow;
+              priv->oflow     = oflow;
 #endif
 
-            /* Effect the changes immediately - note that we do not
-             * implement TCSADRAIN or TCSAFLUSH, only TCSANOW option.
-             * See nuttx/libs/libc/termios/lib_tcsetattr.c
-             */
+              /* Effect the changes immediately - note that we do not
+               * implement TCSADRAIN or TCSAFLUSH, only TCSANOW option.
+               * See nuttx/libs/libc/termios/lib_tcsetattr.c
+               */
 
-            esp32s3_lowputc_disable_all_uart_int(priv, &current_int_sts);
-            ret = esp32s3_setup(dev);
+              esp32s3_lowputc_disable_all_uart_int(priv, &current_int_sts);
+              ret = esp32s3_setup(dev);
 
-            /* Restore the interrupt state */
+              /* Restore the interrupt state */
 
-            esp32s3_lowputc_restore_all_uart_int(priv, &current_int_sts);
-          }
-      }
-      break;
+              esp32s3_lowputc_restore_all_uart_int(priv, &current_int_sts);
+            }
+        }
+        break;
 #endif /* CONFIG_SERIAL_TERMIOS */
 
-    default:
-      ret = -ENOTTY;
-      break;
+      default:
+        ret = -ENOTTY;
+        break;
     }
 
   return ret;
@@ -1086,6 +1091,7 @@ static bool esp32s3_rxflowcontrol(struct uart_dev_s *dev,
 {
   bool ret = false;
   struct esp32s3_uart_s *priv = dev->priv;
+
   if (priv->iflow)
     {
       if (nbuffered == 0 || upper == false)

Reply via email to