Protect MarlinSerial against interrupts
Protect MarlinSerial against interrupts by shielding the CRITICAL_SECTIONs Now with a test if RX_BUFFER_SIZE is in the required range. Code in peek() and read() is now optimized for readability and showing the similarity between the two. Maybe a bit overprotected in checkRx() and store_char(), but now some days without detected errors from this source.
This commit is contained in:
@ -33,16 +33,19 @@
|
||||
#endif
|
||||
|
||||
FORCE_INLINE void store_char(unsigned char c) {
|
||||
uint8_t i = (uint8_t)(rx_buffer.head + 1) % RX_BUFFER_SIZE;
|
||||
CRITICAL_SECTION_START;
|
||||
uint8_t h = rx_buffer.head;
|
||||
uint8_t i = (uint8_t)(h + 1) & (RX_BUFFER_SIZE - 1);
|
||||
|
||||
// if we should be storing the received character into the location
|
||||
// just before the tail (meaning that the head would advance to the
|
||||
// current location of the tail), we're about to overflow the buffer
|
||||
// and so we don't write the character or advance the head.
|
||||
if (i != rx_buffer.tail) {
|
||||
rx_buffer.buffer[rx_buffer.head] = c;
|
||||
rx_buffer.head = i;
|
||||
}
|
||||
// if we should be storing the received character into the location
|
||||
// just before the tail (meaning that the head would advance to the
|
||||
// current location of the tail), we're about to overflow the buffer
|
||||
// and so we don't write the character or advance the head.
|
||||
if (i != rx_buffer.tail) {
|
||||
rx_buffer.buffer[h] = c;
|
||||
rx_buffer.head = i;
|
||||
}
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
|
||||
@ -101,24 +104,32 @@ void MarlinSerial::end() {
|
||||
|
||||
|
||||
int MarlinSerial::peek(void) {
|
||||
if (rx_buffer.head == rx_buffer.tail) {
|
||||
return -1;
|
||||
int v;
|
||||
CRITICAL_SECTION_START;
|
||||
uint8_t t = rx_buffer.tail;
|
||||
if (rx_buffer.head == t) {
|
||||
v = -1;
|
||||
}
|
||||
else {
|
||||
return rx_buffer.buffer[rx_buffer.tail];
|
||||
v = rx_buffer.buffer[t];
|
||||
}
|
||||
CRITICAL_SECTION_END;
|
||||
return v;
|
||||
}
|
||||
|
||||
int MarlinSerial::read(void) {
|
||||
// if the head isn't ahead of the tail, we don't have any characters
|
||||
if (rx_buffer.head == rx_buffer.tail) {
|
||||
return -1;
|
||||
int v;
|
||||
CRITICAL_SECTION_START;
|
||||
uint8_t t = rx_buffer.tail;
|
||||
if (rx_buffer.head == t) {
|
||||
v = -1;
|
||||
}
|
||||
else {
|
||||
unsigned char c = rx_buffer.buffer[rx_buffer.tail];
|
||||
rx_buffer.tail = (uint8_t)(rx_buffer.tail + 1) % RX_BUFFER_SIZE;
|
||||
return c;
|
||||
v = rx_buffer.buffer[t];
|
||||
rx_buffer.tail = (uint8_t)(t + 1) & (RX_BUFFER_SIZE - 1);
|
||||
}
|
||||
CRITICAL_SECTION_END;
|
||||
return v;
|
||||
}
|
||||
|
||||
void MarlinSerial::flush() {
|
||||
@ -131,7 +142,9 @@ void MarlinSerial::flush() {
|
||||
// the value to rx_buffer_tail; the previous value of rx_buffer_head
|
||||
// may be written to rx_buffer_tail, making it appear as if the buffer
|
||||
// were full, not empty.
|
||||
rx_buffer.head = rx_buffer.tail;
|
||||
CRITICAL_SECTION_START;
|
||||
rx_buffer.head = rx_buffer.tail;
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user