uart read fails after ring buffer size elapses

rfleming
Posts: 62
Joined: Tue Oct 09, 2018 12:30 am

uart read fails after ring buffer size elapses

Postby rfleming » Tue May 17, 2022 7:17 am

Hi All,

esp-idf v4.2.2

I can replicate this consistently with 2 different implementations. The first I have seen around for quite some-time over the conventional uart port for stdio. The issues in general only appear to occur when reading data, likely linked to attempting to read large amounts of data that result in a ring buffer overflow. When this occurs once, the ring buffer constantly fails.

With a standard console task (below) if I were to send in 512 bytes of data, but the underlying ring buffer was only 256 bytes large. My task below handles data based on a new line character '\n'. If i send in 512 bytes (an arbitrary amount greater than the buffer) with the final byte being a newline. Then send through repeated 5 bytes of "test\n". After many transmissions, the "test\n" finally comes through. Then if I switch to transmitting "version\n", each time I send this command through, the port continues to read "test\n" for many more times until it has finally cleared from the buffer.

Code: Select all

static void DrvConsole_Tasks(void *pvParameter) {
	// test for bad commands first!
	while (1) {
		// all functions below are non-blocking. couldn't find an optimised one...
		int b = fgetc(stdin);  // just use me as the choice
		// int nread = fread(&c, 1, 1, stdin);	//returns total read
		// uint32_t b = getc(stdin);
		// uint32_t b = getchar();

		if (b != -1) {
			if (b == '\n') {  // line feed, 10d, 0x0A
				// execute cmd
				Debug.Cmd.buf[Debug.Cmd.len] = '\0';  // add null terminator for safety

				if (Debug.Cmd.len > 0)
					Console_CheckCommand((char *)Debug.Cmd.buf);

				Debug.Cmd.len = 0;
			}
			else if (Debug.Cmd.len + 1 >= sizeof(Debug.Cmd.buf)) {
				// the cmd len is about to overrun its buffer. something went wrong, dump the data and start fresh!
				Debug.Cmd.len = 0;
			}
			else {
				Debug.Cmd.buf[Debug.Cmd.len] = b;
				Debug.Cmd.len++;
			}
		}
		else {
			vTaskDelay(100 / portTICK_PERIOD_MS);  // small delay so we don't continuously query! ~100ms
		}
	}
}
I have also noticed something similar when in the same application, but this time using uart1. When I use uart_read_bytes after a few hours of usage. Installing and uninstalling the driver so I can put the rx/tx ios to input no pullups (to save power when sleeping - don't ask, they connect to a peripheral that does weird things if I don't do this). At a certain point in time, possibly because they somehow pick up data when idle, the driver starts doing the delayed delivery of data once again. If i send in 5 bytes, the function reads 5 bytes, but not the 5 bytes I am after. After several reads, it finally spits it out. Its like the ring buffer "knows" how much data is in the buffer, but the tail is pointing to the wrong location.

I hope this is something small that can be worked out!
Ryan.

Who is online

Users browsing this forum: No registered users and 115 guests