Skip to content

Commit 41e8ca7

Browse files
fix(Serial): Uart::write() must not spin when begin() failed
If Serial.begin(baud) fails during hardware init (e.g. an LPUART clocked from LSE can't reach the requested baud rate), uart_init() returns false and _ready is set to false -- but Uart::write() never checks _ready before entering its transmit path. Uart::write(const uint8_t*, size_t) contains: while (!availableForWrite()) { // nop, the interrupt handler will free up space for us } Since the hardware was never actually brought up, the TX interrupt this loop waits on never fires, so once the 63-byte TX ring buffer fills up (a few Serial.print() calls after a failed begin()), this spins forever and the MCU deadlocks permanently. Fix: return 0 immediately if !_ready, before touching the buffer or entering the wait loop, using the same _ready accessor already used elsewhere in this file (see Uart::begin(), which sets it, and the existing operator bool()-style accessor in Serial.h). write(uint8_t) needs no separate guard since it already delegates to this overload. Fixes #3071
1 parent bdea44d commit 41e8ca7

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

‎cores/arduino/Serial.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,14 @@ void Uart::flush(uint32_t timeout)
583583

584584
size_t Uart::write(const uint8_t *buffer, size_t size)
585585
{
586+
// If begin() never brought the hardware up (e.g. the requested baud
587+
// rate can't be reached from the configured kernel clock), the TX
588+
// interrupt this function waits on below will never fire. Bail out
589+
// instead of spinning forever once the TX buffer fills up.
590+
if (!_ready) {
591+
return 0;
592+
}
593+
586594
size_t size_intermediate;
587595
size_t ret = size;
588596
size_t available = availableForWrite();

0 commit comments

Comments
 (0)