Messages in this thread | | | Date | Mon, 06 Sep 1999 18:29:47 +0000 | From | Jorge Ventura <> | Subject | PROBLEM:Serial port stop receiving in asychronous input using "select". |
| |
[1.]Serial port stop receiving in asychronous input using "select".
[2.]The program has a set of descriptors (3) to wake-up the process whenever an event ocurrs on each descriptor. One of them is a descriptor from a serial port to wake-up the process when there is data to be read. After a random time, the drive sudenly stops receiving the data. It seems that the select() does not receive interrupts, that is how I see the problem. I had conected a data analyzer in the serial port and the electrycal interface is ok. I did tests with three computers, the first one was my notebook, an Acer/TI Extensa 616/150 Mhz and the program worked fine. The next was an ASUS motherboard (the production environment) with a Intel/Celeron 266Mhz, the system failure as descripted above. We changed the motherboard to another (ASUS) with Intel/Pentium 450Mhz and the same problem happened.
[3.]Serial port, asynchronous, select.
[4.]Kernel version 2.2.9
[5.]No output Ooops available.
[6.]This is the routine to configure the serial port. The port name I have been using is "/dev/ttyS0" or "/dev/ttyS1".
void config_ports(char *portname) { /* ---- Configura portas ---- */ fd_cua = open(portname, O_RDWR | O_NONBLOCK | O_SYNC | O_NOCTTY); fprintf(stdout, "Configurando porta serial %s ... ", portname); if (fd_cua < 0) { perror("Serial port error"); exit_nicely(conn); } /* -------------- Port settings ---------------- */ tcgetattr(fd_cua,&oldtio); /* save current port settings */ bzero(&newtio, sizeof(struct termios));
newtio.c_iflag = IGNBRK | IGNPAR; newtio.c_oflag = 0; newtio.c_cflag = B4800 | CS7 | PARENB | CLOCAL | CREAD; /* set input mode , no echo,... */ newtio.c_lflag = 0; newtio.c_cc[VMIN] = 1; newtio.c_cc[VTIME] = 0; tcflush(fd_cua, TCIOFLUSH); tcsetattr(fd_cua,TCSANOW,&newtio); fprintf(stdout, "Ok\n"); }
This is the loop to wait the events where the problem happen.
while (!quit) { /* Set read operation */
fd_sock = PQsocket(conn); maxfd = 0; maxfd = max(maxfd, fd_cua); maxfd = max(maxfd, fd_sock); maxfd++; FD_ZERO(&rfds); FD_SET(fd_sock, &rfds); FD_SET(fd_cua, &rfds); /* Set excption operation */ FD_ZERO(&rfds_excpt); FD_SET(fd_cua, &rfds_excpt);
t1 = time(NULL); if (difftime(t1, t0) > 59) { init_gate_time(); send_current_time(t1); t0 = t1; } /* Fica no select aguardando tres eventos possiveis: 1) Timeout = 100 mSeg 2) Porta serial 3) Teclado */ tv_cua.tv_sec = 0; tv_cua.tv_usec = TIMEOUT; retval = select(maxfd, &rfds, NULL, &rfds_excpt, &tv_cua); if (retval == -1) perror("select() interrupted"); /* --- process serial input event --- */ if (FD_ISSET(fd_cua, &rfds)) { port_handler(); continue; } /* --- process data base event --- */ if (FD_ISSET(fd_sock, &rfds)) { db_handler(pnum); }
/* --- Process timeout event --- */ if (tv_cua.tv_usec <= 0 || FD_ISSET(fd_cua, &rfds_excpt)) { tcflush(fd_cua, TCIOFLUSH); poll_next(); } } tcflush(fd_cua, TCIOFLUSH); tcsetattr(fd_cua,TCSANOW,&oldtio); close(fd_cua); sprintf(query, "UNLISTEN rmon_gates;"); res = PQexec(conn, query); PQclear(res); PQfinish(conn); close(hf); }
[7.]
To bypass the problema what I did was: If after 2 seconds I do not receive any data I consider that the problem happen again, close and open the serial port to continue working. Its working in this way.
Thanks in advance
Jorge Ventura
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |