thiagofinelon opened a new issue, #17179:
URL: https://github.com/apache/nuttx/issues/17179
### Description
Summary
I’m running a long-lived application on an ESP32-S3 using the current NuttX
master. After an unpredictable amount of time—sometimes minutes, sometimes
hours—the UART stops behaving correctly: incoming traffic seems to replay older
bytes (e.g., the tail of a previous AT response) instead of delivering the
newest characters. The external device is still transmitting, so it looks as if
the driver is serving a stale buffer.
Environment
SoC: ESP32-S3 (esp32s3-devkit)
UART: 115200 bps, 8N1.
Workload: internal modem/PPP service that keeps the link busy (logs + AT
commands)
Observed Behavior
System boots and UART traffic flows normally.
After a random interval, reads begin returning bytes that were already
consumed earlier (“ghost” data).
From that moment on, the stream never delivers new characters, effectively
stalling the higher-level protocol.
Only a full system reset recovers the port.
Hypothesis: the RX FIFO overflows, leaving the hardware/driver in a wedged
state with old bytes queued.
Mitigation Attempt
To explore the issue, I tweaked arch/xtensa/src/esp32s3/esp32s3_serial.c:
In the ISR I now watch UART_RXFIFO_OVF_INT_ST_M; when set, I call
esp32s3_lowputc_rst_rxfifo(priv) before clearing the status, hoping to drop
corrupted data.
Raised the RX “FIFO full” threshold to 8 bytes so bursts don’t trigger an
interrupt per byte.
Enabled RX timeout with a threshold of 10, so shorter frames still wake the
ISR even if they never fill the FIFO.
These changes seem to postpone the failure but I’m not yet convinced they
fully solve it.
Questions for the maintainers
Does resetting the FIFO on overflow and adjusting the thresholds sound like
the right approach, or am I just hiding the real root cause?
Are there recommended settings or patches for handling long-term,
high-volume UART traffic on the ESP32-S3 under NuttX?
Alterations in esp32s3_serial.c : uart_handler()
```
/* ISR additions */
uint32_t rx_ovf_mask = UART_RXFIFO_OVF_INT_ST_M;
...
if ((int_status & rx_mask) != 0)
{
uart_recvchars(dev);
modifyreg32(UART_INT_CLR_REG(priv->id), rx_mask, rx_mask);
}
if ((int_status & rx_ovf_mask) != 0)
{
esp32s3_lowputc_rst_rxfifo(priv);
modifyreg32(UART_INT_CLR_REG(priv->id), rx_ovf_mask, rx_ovf_mask);
}
```
Alterations in esp32s3_serial.c : esp32s3_setup()
```
static int esp32s3_setup(struct uart_dev_s *dev)
{
struct esp32s3_uart_s *priv = dev->priv;
const uint32_t ticks_tout = 10U;
const uint32_t rx_fifo_thrhd = 8U;
...
modifyreg32(UART_CONF1_REG(priv->id), UART_RXFIFO_FULL_THRHD_M,
rx_fifo_thrhd << UART_RXFIFO_FULL_THRHD_S);
modifyreg32(UART_CONF1_REG(priv->id),
UART_RX_TOUT_THRHD_M | UART_RX_TOUT_EN_M,
(ticks_tout << UART_RX_TOUT_THRHD_S) |
UART_RX_TOUT_EN_M);
...
}
```
### Verification
- [x] I have verified before submitting the report.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]