Page 1 of 1

How to use select() on default uart console for timeout on blocking read

Posted: Sat Oct 04, 2025 11:58 pm
by sn0wbl1nd
Hi all. I have a custom `console_get()` function I use to implement a blocking read operation with a timeout. This implementation allows me to use the REPL loop to, for example, interact with the watchdog.

I had this working well on an ESP32-S3, but currently working on an ESP32 it is not working. The console is different on the ESP32, using the default UART setup. I have studied the UART select example but don't see where I might have gone wrong.

The code is below - it should work. I assume the problem is the interaction between VFS and the uart. I use the same console initialization used in the advanced console example. I don't use linenoise. Perhaps the UART has a hardware buffer that cannot be used with select?

I appreciate your help.

Code: Select all

int console_get(const char **p_line) {
	fd_set readfds;
	struct timeval tv;
	int rval = ESP_OK;
	int time_count = 0;
	static char c = 0;
	if (c=='\n') {		// reset line buffer
		buffer_ix = 0;
		c = 0;
	}
	while ((time_count<timeout) && (c!='\n')) {
		FD_ZERO(&readfds);
		FD_SET(fd_in, &readfds);
		tv.tv_sec = 1; 		// 1 sec timeout
		tv.tv_usec = 0;
		int result = select(fd_in+1, &readfds, NULL, NULL, &tv);
		if (result == -1) {
			rval = -1;		// note that this will only be returned on the last cycle
		} else if (result) {		// data
			result = read( fd_in, &c, 1);
			if (result<=0) {
				rval = -2;		// should not happen
			}
			else {
				if ((c=='\n') || (c=='\r')) {		// done
					rval = buffer_ix;	// string size
					buffer[buffer_ix] = 0;
				}
				else {
					buffer[buffer_ix++] = c;
					if ((buffer_ix+1)==BUFFER_SIZE) {
						c = '\n';		// clear buffer on next entry
						buffer[buffer_ix] = 0;
					}
				}
			}
		}
		time_count++;
	}
	if (c=='\n') {
		*p_line = buffer;
		rval = buffer_ix;
	}
	return rval;
}

Re: How to use select() on default uart console for timeout on blocking read

Posted: Sun Oct 05, 2025 1:16 am
by sn0wbl1nd
Typical - I post for help and figure something out. The select() operation is working fine. There is an issue with my use of the watchdog timer.