[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/