Skip to content

Commit a73e167

Browse files
committed
Merge pull request #1213 from alltheblinkythings/cbuf_interrupts
Interrupt safety fixes for HardwareSerial
2 parents 8d4287b + 55e0dab commit a73e167

File tree

2 files changed

+31
-13
lines changed

2 files changed

+31
-13
lines changed

cores/esp8266/HardwareSerial.cpp

+29-11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <inttypes.h>
3030
#include "Arduino.h"
3131
#include "cbuf.h"
32+
#include "interrupts.h"
3233

3334
extern "C" {
3435
#include "osapi.h"
@@ -556,6 +557,7 @@ int HardwareSerial::available(void) {
556557
int result = 0;
557558

558559
if (_uart != NULL && _uart->rxEnabled) {
560+
InterruptLock il;
559561
result = static_cast<int>(_rx_buffer->getSize());
560562
}
561563

@@ -570,6 +572,7 @@ int HardwareSerial::peek(void) {
570572
if(_uart == 0)
571573
return -1;
572574
if(_uart->rxEnabled) {
575+
InterruptLock il;
573576
return _rx_buffer->peek();
574577
} else {
575578
return -1;
@@ -580,6 +583,7 @@ int HardwareSerial::read(void) {
580583
if(_uart == 0)
581584
return -1;
582585
if(_uart->rxEnabled) {
586+
InterruptLock il;
583587
return _rx_buffer->read();
584588
} else {
585589
return -1;
@@ -590,6 +594,7 @@ int HardwareSerial::availableForWrite(void) {
590594
if(_uart == 0)
591595
return 0;
592596
if(_uart->txEnabled) {
597+
InterruptLock il;
593598
return static_cast<int>(_tx_buffer->room());
594599
} else {
595600
return 0;
@@ -604,28 +609,41 @@ void HardwareSerial::flush() {
604609
if(!_written)
605610
return;
606611

607-
while(_tx_buffer->getSize() || uart_get_tx_fifo_room(_uart) < UART_TX_FIFO_SIZE)
612+
while(true) {
613+
{
614+
InterruptLock il;
615+
if(_tx_buffer->getSize() == 0 &&
616+
uart_get_tx_fifo_room(_uart) >= UART_TX_FIFO_SIZE) {
617+
break;
618+
}
619+
}
608620
yield();
609-
621+
}
610622
_written = false;
611623
}
612624

613625
size_t HardwareSerial::write(uint8_t c) {
614626
if(_uart == 0 || !_uart->txEnabled)
615627
return 0;
616628
_written = true;
617-
size_t room = uart_get_tx_fifo_room(_uart);
618-
if(room > 0 && _tx_buffer->empty()) {
619-
uart_transmit_char(_uart, c);
620-
return 1;
621-
}
622629

623-
while(_tx_buffer->room() == 0) {
630+
while(true) {
631+
{
632+
InterruptLock il;
633+
if(_tx_buffer->empty()) {
634+
if(uart_get_tx_fifo_room(_uart) > 0) {
635+
uart_transmit_char(_uart, c);
636+
} else {
637+
_tx_buffer->write(c);
638+
uart_arm_tx_interrupt(_uart);
639+
}
640+
break;
641+
} else if(_tx_buffer->write(c)) {
642+
break;
643+
}
644+
}
624645
yield();
625646
}
626-
627-
_tx_buffer->write(c);
628-
uart_arm_tx_interrupt(_uart);
629647
return 1;
630648
}
631649

cores/esp8266/cbuf.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ class cbuf {
113113
return (ptr == _bufend) ? _buf : ptr;
114114
}
115115

116-
size_t _size;
116+
const size_t _size;
117117
char* _buf;
118-
char* _bufend;
118+
const char* const _bufend;
119119
char* _begin;
120120
char* _end;
121121
};

0 commit comments

Comments
 (0)