aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Holman <john.g.holman@gmail.com>2017-10-24 22:18:38 +0100
committerMartino Facchin <m.facchin@arduino.cc>2017-11-13 17:46:47 +0100
commitd50e59781ecfd80a366cd0bb0b30374b1536247a (patch)
treebf8b8b8a9700b5c5913937a1ed83712f1339568e
parentf1c4cc631620f6486706a06580011a2e0dbd77e5 (diff)
Create macro to guard critical sections for large transmit buffers
New macro TX_BUFFER_ATOMIC makes the following code block atomic only if the transmit buffer is larger than 256 bytes. SREG is restored on completion. The macro is then used to simplify code for availableForWrite()
-rw-r--r--cores/arduino/HardwareSerial.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index 5cd89e5..75e079f 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
+#include <util/atomic.h>
#include "Arduino.h"
#include "HardwareSerial.h"
@@ -76,6 +77,13 @@ void serialEventRun(void)
#endif
}
+// macro to guard critical sections when needed for large TX buffer sizes
+#if (SERIAL_TX_BUFFER_SIZE>256)
+#define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+#else
+#define TX_BUFFER_ATOMIC
+#endif
+
// Actual interrupt handlers //////////////////////////////////////////////////////////////
void HardwareSerial::_tx_udr_empty_irq(void)
@@ -177,15 +185,13 @@ int HardwareSerial::read(void)
int HardwareSerial::availableForWrite(void)
{
-#if (SERIAL_TX_BUFFER_SIZE>256)
- uint8_t oldSREG = SREG;
- cli();
-#endif
- tx_buffer_index_t head = _tx_buffer_head;
- tx_buffer_index_t tail = _tx_buffer_tail;
-#if (SERIAL_TX_BUFFER_SIZE>256)
- SREG = oldSREG;
-#endif
+ tx_buffer_index_t head;
+ tx_buffer_index_t tail;
+
+ TX_BUFFER_ATOMIC {
+ head = _tx_buffer_head;
+ tail = _tx_buffer_tail;
+ }
if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
return tail - head - 1;
}