aboutsummaryrefslogtreecommitdiff
path: root/cores
diff options
context:
space:
mode:
authorJohn Holman <john.g.holman@gmail.com>2017-10-25 10:06:37 +0100
committerMartino Facchin <m.facchin@arduino.cc>2017-11-13 17:46:47 +0100
commite9e43cf58302a16b606ed6fd0b5b2c73efc2ada2 (patch)
treec28b2f58d9fc2a790c9e675cfb57ba9fe75f1870 /cores
parentd50e59781ecfd80a366cd0bb0b30374b1536247a (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')
-rw-r--r--cores/arduino/HardwareSerial.cpp11
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;
}