OK.. update...
I made a small "crash program" > see code below.
It basically reads from the serial port over usb every 100us.
It reads in "blocking mode".
The serial port is getting "every second 812byte datablock on /dev/ttyUSB0; baudrate 11520"
My original program runs a continuous loop that calls several service functions. The read function is called every 250ms. However... when in blocking mode at least half of them gets blocked so "average looptime" would have been around 500ms.
This "crash" program has a looptime of 100us BUT is of cause blocked during the gaps in data availability.
logging shows I'm getting 151loops per minute. That's 397ms on average. Oops... that is not much faster.
I guess the 812 datablock gets read in about 3 calls after which the "end of the second" needs to be awaited until the next block.
In addition to the read() calls I have set an interval timer for 1ms (thank you brother for handing me this code). This timer interrupts the read(). Running on the assumption that the blocking call has difficulty handling interrupts this is intended to give that an extra stress.
Logging is written to a network connected 2nd computer so even if the computer crashes I will have the logging.
My main application is running in parallel. Without reading the serial port.
Console is working. screensaver no longer kicking in.
So...
It's running.
Now wait....
My crash test program:
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>
#include <stddef.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/select.h>
//#include <syslog.h>
#define usDELAYTIME 100
#define minLOGINTERVAL 10
#define meterREAD 1
#define meterFD 2
#define meterSELECT 4
#define meterREFRESH 8
#define meterBLOCKING 16
#define BUFSIZE 8191
int meterMODE = meterREAD | meterBLOCKING;
char logfile[128] = "/remote/home/tc/crashlog.txt";
struct termios pts; // interface settings
int fd;
void usDelay(int len)
{ struct timespec delay;
delay.tv_sec = 0;
delay.tv_nsec = len;
delay.tv_nsec *= 1000; //1000=us, set in us * 10e3
nanosleep(&delay, NULL);
}
static void dummy_func(int sig)
{
}
int start_meter()
{ int flags;
/* some things we want to set arbitrarily */
pts.c_lflag &= ~ICANON;
pts.c_lflag &= ~(ECHO | ECHOCTL | ECHONL);
pts.c_cflag |= HUPCL;
pts.c_cc[VMIN] = 1;
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.
*/
pts.c_oflag |= ONLCR;
pts.c_iflag &= ~ICRNL;
/* set hardware flow control by default */
pts.c_cflag |= CRTSCTS;
pts.c_iflag &= ~(IXON | IXOFF | IXANY);
/* set 115200 bps speed by default */
cfsetospeed(&pts, B115200);
cfsetispeed(&pts, B115200);
fd = open("/dev/ttyUSB0", O_RDWR);
if (fd>=0)
{ flags = fcntl(fd, F_GETFL);
if ( !(meterMODE & meterBLOCKING) )
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
tcsetattr(fd, TCSANOW, &pts);
}
return 1;
}
int main()
{ char buf[BUFSIZE+1];
fd_set fd_check;
struct tm *tm_now;
time_t now, tstamp;
struct timeval wait = {0};
FILE *f_log;
int j =0;
unsigned long long count =0;
unsigned long long kcount =0;
struct itimerval interval = { 0 };
interval.it_interval.tv_sec = 0;
interval.it_interval.tv_usec = 1000; // repeat interval after 1st trigger; 1000 = 1ms
interval.it_value.tv_sec = 0;
interval.it_value.tv_usec = 1000; // time until first trigger
start_meter( );
if (fd < 0)
{ printf("cannot open device");
exit(1);
}
setitimer(ITIMER_REAL, &interval, NULL); //set interval timer
signal(SIGALRM, dummy_func); // dummy interrupt call
while (1)
{ if (meterMODE & meterFD)
{ FD_ZERO(&fd_check);
FD_SET(fd, &fd_check);
}
if (meterMODE & meterSELECT)
select(fd +1, &fd_check, NULL, NULL, &wait);
if (meterMODE & meterFD)
FD_ISSET(fd, &fd_check);
if (meterMODE & meterREAD)
{ j = read(fd, buf, BUFSIZE); // read
}
usDelay(usDELAYTIME);
count++;
time(&now);
if (now > tstamp+60*minLOGINTERVAL )
{ tm_now = localtime(&now);
tstamp = now;
kcount+= count/1000;
count %= 1000;
f_log = fopen(logfile, "a");
if (f_log!=NULL)
fprintf(f_log, "mon day: %2d %2d | hh:mm:ss: %02d:%02d:%02d | Still alive after %lldk + %lld loops\n",
tm_now->tm_mon+1, tm_now->tm_mday, tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec, kcount, count);
fclose(f_log);
}
}
exit(0);
}