From 1ca5dc8496c67dcffd144b1071c5c045733a5461 Mon Sep 17 00:00:00 2001 From: Pavel Vymetálek Date: Mon, 2 Nov 2026 09:26:46 +0100 Subject: Cleaner serial port initialization, detection of serial device disconnection --- sercp.c | 66 ++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/sercp.c b/sercp.c index 7acda1e..5eb087f 100644 --- a/sercp.c +++ b/sercp.c @@ -366,6 +366,14 @@ static void SignalHandler(int sig) { exit(EXIT_FAILURE); } +//***************************************************************************** + +void SerialDeviceError(void) { + CloseSerialPort(); + fprintf(stderr, "\n[ERROR] The device %s has been disconnected or is invalid!\n", SERIALDEVICE); + exit(-1); +} + //***************************************************************************** // @@ -583,6 +591,10 @@ uint8_t WaitReadAck(void) { memset(buf_ack, 0, 8); while (1) { result = poll (spolfd_serial, 1, 300); // 200ms timeout + if (spolfd_serial->revents & (POLLHUP | POLLERR | POLLNVAL)) { + SerialDeviceError(); + break; + } if (result == 0) { // nothing is comming continue; @@ -671,6 +683,11 @@ void sercpRecv(void) { while (is_continue) { #ifndef _WIN32 result = poll (spolfd_serial, 1, 200); // 200ms timeout + if (spolfd_serial->revents & (POLLHUP | POLLERR | POLLNVAL)) { + SerialDeviceError(); + break; + } + if (result == 0) { // nothing is comming continue; @@ -988,6 +1005,7 @@ int OpenUart() { return (0); #else struct termios oldtio, newtio; + speed_t serial_speed; /* open the device to be non-blocking (read will return immediatly) */ serial_fd = open(SERIALDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); // | O_NDELAY if (serial_fd < 0) { @@ -1016,61 +1034,59 @@ int OpenUart() { tcgetattr(serial_fd, &oldtio); /* save current port settings */ memset(&newtio, 0, sizeof (newtio)); switch (baud_rate){ +#ifdef B921600 case 921600: - newtio.c_cflag = B921600; + serial_speed = B921600; break; +#endif +#ifdef B460800 case 460800: - newtio.c_cflag = B460800; + serial_speed = B460800; break; +#endif case 230400: - newtio.c_cflag = B230400; + serial_speed = B230400; break; case 115200: - newtio.c_cflag = B115200; + serial_speed = B115200; break; case 57600: - newtio.c_cflag = B57600; + serial_speed = B57600; break; case 38400: - newtio.c_cflag = B38400; + serial_speed = B38400; break; case 19200: - newtio.c_cflag = B19200; + serial_speed = B19200; break; case 9600: - newtio.c_cflag = B9600; + serial_speed = B9600; break; case 4800: - newtio.c_cflag = B4800; + serial_speed = B4800; break; case 2400: - newtio.c_cflag = B2400; + serial_speed = B2400; break; case 1200: - newtio.c_cflag = B1200; + serial_speed = B1200; break; default: baud_rate = 38400; - newtio.c_cflag = B38400; + serial_speed = B38400; break; } - cfsetospeed(&newtio, baud_rate); - cfsetispeed(&newtio, baud_rate); // set ispeed same as ospeed (see POSIX) + newtio.c_cflag = CS8 | CLOCAL | CREAD; + if (is_flow_control_hw) { #if defined (__APPLE__) || defined (BSD) - if (is_flow_control_none) { - printf("Sorry, flow control is not tested on this platform\n"); - newtio.c_cflag |= CS8 | CLOCAL | CREAD | HUPCL; - } else { - newtio.c_cflag |= CS8 | CLOCAL | CREAD | CCTS_OFLOW | CRTS_IFLOW | HUPCL; - } + newtio.c_cflag |= CCTS_OFLOW | CRTS_IFLOW; #else - if (is_flow_control_hw) { // standard CTS/RTS flow control for old .sercp protocol - newtio.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS; - } else { - newtio.c_cflag |= CS8 | CLOCAL | CREAD; - } + newtio.c_cflag |= CRTSCTS; #endif + } + cfsetospeed(&newtio, serial_speed); + cfsetispeed(&newtio, serial_speed); // set ispeed same as ospeed (see POSIX) newtio.c_iflag &= ~(IXON | IXOFF | IXANY); newtio.c_oflag &= ~(OPOST); newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // raw input -- cgit