Prevent buffer retransmission when transmit buffer is empty

Moving the head buffer pointer and setting interrupt flag is now
atomic in write(). Previously an intervening ISR could empty the
buffer before the second ISR is triggered causing retransmission.

Fixes: #3745 (original issue only)
This commit is contained in:
John Holman 2017-10-25 10:06:37 +01:00 committed by Martino Facchin
parent d50e59781e
commit e9e43cf583
1 changed files with 8 additions and 3 deletions

View File

@ -246,9 +246,14 @@ size_t HardwareSerial::write(uint8_t c)
}
_tx_buffer[_tx_buffer_head] = c;
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
// make atomic to prevent execution of ISR between setting the
// head pointer and setting the interrupt flag resulting in buffer
// retransmission
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
}
return 1;
}