Hi!
I've found some issue in the Serial.cpp code that I want to share here:
As MultiWii uses its own serial functions, it also introduces some different (better suitable) behaviour when the serial RX ring buffers overflow: The original Arduino "HardwareSerial" library keeps the old data in the buffer and just skips the new data not fitting in anymore:
Code: Select all
inline void store_char(unsigned char c, ring_buffer *buffer)
{
uint8_t i = (uint8_t)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// 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 != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
MultiWii throws out the oldest data so that always the freshest data is in the buffer:
Code: Select all
void store_uart_in_buf(uint8_t data, uint8_t portnum) {
.
.
.
uint8_t h = serialHeadRX[portnum];
serialBufferRX[h++][portnum] = data;
if (h >= RX_BUFFER_SIZE) h = 0;
serialHeadRX[portnum] = h;
}
But there is a design flaw: The code above doesn't adjust the serialTailRX-Pointer, when writing new data to a full buffer. This leads to (virtually) completely flushing the buffer by overwriting it with just one byte.
Proposal for solution (untested):
Code: Select all
void store_uart_in_buf(uint8_t data, uint8_t portnum) {
.
.
.
uint8_t h = serialHeadRX[portnum];
serialBufferRX[h++][portnum] = data;
if (h >= RX_BUFFER_SIZE) h = 0;
serialHeadRX[portnum] = h;
if (serialTailRX[portnum] == h)
if (++serialTailRX[portnum] == RX_BUFFER_SIZE) serialTailRX[portnum] = 0;
}
Greets,
Edgar