From afbc049cc91e91bbd8f50586fdfb3ce874d3f91e Mon Sep 17 00:00:00 2001 From: Christopher Pascoe Date: Wed, 9 Dec 2015 22:51:57 -0800 Subject: [PATCH 1/2] Make the circular buffer's _size and _bufend members immutable. --- cores/esp8266/cbuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/cbuf.h b/cores/esp8266/cbuf.h index 087e7200b..02b612c5c 100644 --- a/cores/esp8266/cbuf.h +++ b/cores/esp8266/cbuf.h @@ -113,9 +113,9 @@ class cbuf { return (ptr == _bufend) ? _buf : ptr; } - size_t _size; + const size_t _size; char* _buf; - char* _bufend; + const char* const _bufend; char* _begin; char* _end; }; From 55e0dab799653d7e16f262e3693195570e068854 Mon Sep 17 00:00:00 2001 From: Christopher Pascoe Date: Sun, 13 Dec 2015 19:39:47 -0800 Subject: [PATCH 2/2] Protect HardwareSerial's cbuf usage with InterruptLock. --- cores/esp8266/HardwareSerial.cpp | 40 +++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 78108bee7..3527b4a86 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -29,6 +29,7 @@ #include #include "Arduino.h" #include "cbuf.h" +#include "interrupts.h" extern "C" { #include "osapi.h" @@ -556,6 +557,7 @@ int HardwareSerial::available(void) { int result = 0; if (_uart != NULL && _uart->rxEnabled) { + InterruptLock il; result = static_cast(_rx_buffer->getSize()); } @@ -570,6 +572,7 @@ int HardwareSerial::peek(void) { if(_uart == 0) return -1; if(_uart->rxEnabled) { + InterruptLock il; return _rx_buffer->peek(); } else { return -1; @@ -580,6 +583,7 @@ int HardwareSerial::read(void) { if(_uart == 0) return -1; if(_uart->rxEnabled) { + InterruptLock il; return _rx_buffer->read(); } else { return -1; @@ -590,6 +594,7 @@ int HardwareSerial::availableForWrite(void) { if(_uart == 0) return 0; if(_uart->txEnabled) { + InterruptLock il; return static_cast(_tx_buffer->room()); } else { return 0; @@ -604,9 +609,16 @@ void HardwareSerial::flush() { if(!_written) return; - while(_tx_buffer->getSize() || uart_get_tx_fifo_room(_uart) < UART_TX_FIFO_SIZE) + while(true) { + { + InterruptLock il; + if(_tx_buffer->getSize() == 0 && + uart_get_tx_fifo_room(_uart) >= UART_TX_FIFO_SIZE) { + break; + } + } yield(); - + } _written = false; } @@ -614,18 +626,24 @@ size_t HardwareSerial::write(uint8_t c) { if(_uart == 0 || !_uart->txEnabled) return 0; _written = true; - size_t room = uart_get_tx_fifo_room(_uart); - if(room > 0 && _tx_buffer->empty()) { - uart_transmit_char(_uart, c); - return 1; - } - while(_tx_buffer->room() == 0) { + while(true) { + { + InterruptLock il; + if(_tx_buffer->empty()) { + if(uart_get_tx_fifo_room(_uart) > 0) { + uart_transmit_char(_uart, c); + } else { + _tx_buffer->write(c); + uart_arm_tx_interrupt(_uart); + } + break; + } else if(_tx_buffer->write(c)) { + break; + } + } yield(); } - - _tx_buffer->write(c); - uart_arm_tx_interrupt(_uart); return 1; }