Oops, still running after 24hrs but I miscounted a day and manually stopped while I could better have let it run for an other day.
So:
- running with blocking read() without select() for 24hrs without crash
- accidentally manually stopped it
- restarted. I will let it run for 48hrs unless it crashes before that
For those interested, this is how the code looks likes
I use enable_meter as a global variable that is read from a configuration file to control what functions are active.
Selection bit masks:
#define meterREAD 1
#define meterFD 2
#define meterSELECT 4
#define meterREFRESH 8
#define meterBLOCKING 16
Initialize (call once):
int start_meter(tmeter *X)
{ int flags;
meterMODE = enable_meter;
/* some things we want to set arbitrarily */
(X->pts).c_lflag &= ~ICANON;
(X->pts).c_lflag &= ~(ECHO | ECHOCTL | ECHONL);
(X->pts).c_cflag |= HUPCL;
(X->pts).c_cc[VMIN] = 1;
(X->pts).c_cc[VTIME] = 0;
/* Standard CR/LF handling: this is a dumb terminal.
* Do no translation:
* no NL -> CR/NL mapping on output, and
* no CR -> NL mapping on input.
*/
(X->pts).c_oflag |= ONLCR;
(X->pts).c_iflag &= ~ICRNL;
/* set hardware flow control by default */
(X->pts).c_cflag |= CRTSCTS;
(X->pts).c_iflag &= ~(IXON | IXOFF | IXANY);
/* set 115200 bps speed by default */
cfsetospeed(&(X->pts), B115200);
cfsetispeed(&(X->pts), B115200);
X->fd = open(X->dev, O_RDWR);
if (X->fd>=0)
{ flags = fcntl(X->fd, F_GETFL);
if ( !(meterMODE & meterBLOCKING) )
fcntl(X->fd, F_SETFL, flags | O_NONBLOCK);
tcsetattr(X->fd, TCSANOW, &(X->pts));
X->SecLastRefresh = SECNOW();
}
return 1;
}
service (call every 250ms):
int do_readmeter(tmeter *X)
{ static int i=0;
static int j=0;
static int n=0;
static int k=0;
static char buf[BUFSIZE+1];
fd_set fd_check;
struct timeval wait = {0};
meterMODE = enable_meter;
if (meterMODE & meterFD)
{ FD_ZERO(&fd_check);
FD_SET(X->fd, &fd_check);
}
if (meterMODE & meterSELECT)
select(X->fd +1, &fd_check, NULL, NULL, &wait);
if (meterMODE & meterFD)
FD_ISSET(X->fd, &fd_check);
//if (FD_ISSET(X->fd, &fd_check) ) //this was originally there but removed for this investigation
if (meterMODE & meterREAD)
{ j = read(X->fd, &buf[i], BUFSIZE-i);
while (j>0)
{ buf[i] &=0x007F;
if ( buf[i]=='\n' )
{ do_parsemeter(buf, X);
i++; j--;
n=i;
i=0;
for (k=0; k<=j; k++)
buf[i+k]=buf[i+n+k];
}
else
{ i++; j--;
}
if (i >= BUFSIZE)
{ i=0; j=0;
}
}
}
return 1;
}