diff options
author | John Holman <john.g.holman@gmail.com> | 2017-10-25 10:06:37 +0100 |
---|---|---|
committer | Martino Facchin <m.facchin@arduino.cc> | 2017-11-13 17:46:47 +0100 |
commit | e9e43cf58302a16b606ed6fd0b5b2c73efc2ada2 (patch) | |
tree | c28b2f58d9fc2a790c9e675cfb57ba9fe75f1870 /cores/arduino | |
parent | d50e59781ecfd80a366cd0bb0b30374b1536247a (diff) |
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)
Diffstat (limited to 'cores/arduino')
-rw-r--r-- | cores/arduino/HardwareSerial.cpp | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 75e079f..560ef3a 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -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; } |