Hardware serial_read dropping characters.

Status
Not open for further replies.

palesius

Member
I was attempting to create a serial_read function to add to serial1.c and it works okay at low speeds but seems to randomly drop characters when receiving a larger transmission (still well under the buffer size).

This isn't a big deal since I can always just use serial_getchar repeatedly, but it seems that a version to read multiple characters in sequence would save a few cycles.

Was this something that was left out of the original library because it just wasn't practical/worth the time saving? Or just because it wasn't needed.

Here was my stab at it, which has some sort of issue, most likely due to my lack of proficiency at C or misunderstanding of the existing codebase.
Code:
//reads up to <size> bytes into the buffer <buf>, return the number of bytes actually read
int serial_read(void *buf,unsigned int size)
{
	uint8_t *p = (uint8_t *)buf;
	uint8_t head, tail, end;
	head = rx_buffer_head;
	tail = rx_buffer_tail;
	if (size>=RX_BUFFER_SIZE) {end=tail+RX_BUFFER_SIZE;} else {end=tail+size;}
	int count=0;
	int i;
	if (end>=RX_BUFFER_SIZE && head<tail) {
		//copy form tail up to end of buffer
		for(i=tail+1;i<RX_BUFFER_SIZE;i++) {*p++=rx_buffer[i];}
		*p++=rx_buffer[0];
		count=count+RX_BUFFER_SIZE-tail;
		end=end-RX_BUFFER_SIZE;
		tail=0;
	}
	if (head == tail) {
		rx_buffer_tail = tail;
		return count;
	}
	if (end>head) {end=head;}
	//copy from tail up to end marker
	for(i=tail+1;i<=end;i++) {*p++=rx_buffer[i];}
	count=count+end-tail;
	rx_buffer_tail = end;
	return count;
}
 
As a quick sanity check, try disabling interrupts at the beginning of your function, and enable them right before each return. If that fixes the problem, then you can try to find a more optimal way to manage shared access to the buffer.

If that doesn't fix the problem, well, at least ruling out race conditions is a good first step.
 
Status
Not open for further replies.
Back
Top