Здравствуйте, уважаемые. Исходные данные, имеется некоторое устройство которое с частотой 10Гц посылает на компьютер пакет с данными (16 байт). Устройство подключено к ПК с помощью переходника USB to COM. Если программа, код который приведен ниже, стартует в первый раз после перезагрузки/включения, то она отрабатывает некорректно, то есть получается как будто пакеты приходят не с частотой 10Гц а к примеру 3, или 5 всегда по разному. А если выйти из программы после неудачного старта и снова ее запустить, то все работает как часы.
Теперь вопрос в чем может быть причина такого странного поведения?
P/S opensuse 11.3, xfce, устройство подключено на юсб, на этот же комп подключена GPS Garmin LVC18 но на реальный физический ком-порт(может быть причина в прерываниях или еще в чем)
Программа:
Функция инициализации ком порта
int opendevice(char* device, int speed)
{
struct termios new;
speed_t sspeed;
int res = 0, fd = 0;
if(( fd = open(device, O_RDWR | O_NDELAY | O_NOCTTY)) < 0){
perror("Can not open device");
return -1;
}
switch(speed)
{
case 2400:
sspeed = B2400;
break;
case 4800:
sspeed = B4800;
break;
case 9600:
sspeed = B9600;
break;
case 19200:
sspeed = B19200;
break;
case 38400:
sspeed = B38400;
break;
case 115200:
sspeed = B115200;
break;
}
memset (&new, 0, sizeof (new));
cfmakeraw(&new);
new.c_cflag &= ~PARENB; // disable parent bit
new.c_cflag &= ~CSTOPB;// disable parent bit
new.c_cflag &= ~CSIZE; // 1 stop bit
new.c_cflag |= CS8; // 8bit data
new.c_cflag |= CREAD; // Enable Receiver
new.c_cflag |= CLOCAL; // Ignore modem control lines.
new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
new.c_oflag &= ~OPOST;
//new.c_cc[VMIN] = 1; // 1 simbols for read
//new.c_cc[VTIME] = 1; // Time of reading of 1 symbol
res = cfsetispeed(&new, sspeed); //baud rate 4800
if (res<0){
perror("Can not set input speed of device");
fprintf(filelog,"FATAL ERROR: Can not set input speed of device %s. Time %s\n",device,ctime(&ftmcreated));
return -1;
};
res = cfsetospeed(&new, sspeed);
if (res<0){
perror("Can not set output speed of device");
fprintf(filelog,"FATAL ERROR: Can not set output speed of device %s. Time %s\n",device,ctime(&ftmcreated));
return -1;
};
tcflush(fd, TCIOFLUSH);
res = tcsetattr(fd, TCSAFLUSH, &new);
if (res<0){
perror("Can not set attribute to device");
fprintf(filelog,"FATAL ERROR: Can not set attribute of device %s. Time %s\n",device,ctime(&ftmcreated));
return -1;
};
return fd;
}.
Функция main
int main(int argc, char** argv)
{
unsigned char chs,indx=0,filename[256], devname[256];
unsigned char data[16];
int speed = 4800,dmn;
strcpy(devname, "/dev/ttyUSB0");
filelog=fopen("/station/data/logfile.txt","a"); // создаем лог файл
if(!filelog){
printf("Cant create file with logs!\n");
exit(1);
}
int c, fd;
if (argc > 1) { // открываем девайс
while (1) {
c = getopt (argc, argv, "d:s:h");
if (c == -1)
break;
switch (c) {
case '\0':
fprintf(stderr,"Error: Unknown command ");
print_help ();
return -1;
break;
case 'h':
print_help ();
return 0;
break;
case 's':
speed = atoi(optarg);
break;
case 'd':
strcpy (devname, optarg);
break;
default:
print_help ();
return 0;
break;
}
}
}
////// Create files ////////////////
(void) gettimeofday (&tmvl, NULL); // получаем текущее время и дату в секундах от начала эпохи
gmt = *gmtime(&tmvl.tv_sec); // преобразовавыем его в структуру
sprintf (filename, "%s/%4.4d%2.2d%2.2d%2.2d%2.2d.mvs",
dir,
gmt.tm_year + 1900,
gmt.tm_mon + 1,
gmt.tm_mday, gmt.tm_hour,gmt.tm_min); // создаем имя файла с ткущей датой формат ГГГГММДДЧЧММ.mvs
filedata=fopen(filename,"w");
if(!filedata) fprintf(filelog,"Cant create data file with name %s! Time %s\n",filename,ctime(&ftmcreated));
ftmcreated=tmvl.tv_sec;
dmn=daemon(0,1);
if(dmn<0){
printf("MVS daemon not started!\n");
fprintf(filelog,"MVS daemon not started! Time %s\n",devname,ctime(&ftmcreated));
exit(1);
}
printf("MVS DAEMON STARTED\n Press ENTER\n");
if( (fd = opendevice(devname, speed)) < 0) {
fprintf(stderr,"FATAL ERROR: Can not open device %s\n",devname);
fprintf(filelog,"FATAL ERROR: Can not open device %s. Time %s\n",devname,ctime(&ftmcreated));
exit (1);
}
FILE *raw;
raw=fopen("/station/data/raw.bin","w+b"); //debug
FILE *dev;
dev=fopen(devname,"r+b");
while (1){
chs=fgetc(dev);
//fwrite(&chs,sizeof(char),1,raw);
if((chs == 'C' ) && (indx == 0 )) {data[0]=chs; indx++;} // sync 'C'
if((chs == 'A' ) && (indx == 1 )) {data[1]=chs; indx++;} // sync 'A'
if((chs == 'D' ) && (indx == 2 )) {data[2]=chs; indx++;} // sync 'D'
if((chs == 'R' ) && (indx == 3 )) {data[3]=chs; indx++;} // sync 'R'
if((chs == 0x0 ) && (indx == 4 )) {data[4]=chs; indx++;} // sync '0' channel 0
if((data[0]=='C')&&(data[1]=='A')&&(data[2]=='D')&&(data[3]=='R')&&(data[4]==0x0)&&(indx>4)){
data[indx-1] = chs;
indx++;
if((data[0]=='C')&&(data[1]=='A')&&(data[2]=='D')&&(data[3]=='R')&&(data[4]==0x0)&&(data[8]==0x1)&&(data[12]==0x2)&&(indx==17)){ // verify channel number
//printf("INDX %d DATA %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \n",indx,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],data[9],data[10],data[11],data[12],data[13],data[14],data[15]);
crtfile(data,indx); - функция обработки полученных данных, в данном случае она не важна
indx=0;
}
else{
if(indx==17){
//fprintf(filelog,"Sync corrupt CADR has %s\n",data);
fwrite(data,sizeof(data),1,raw);
}
}
}
}
fclose (dev);
fclose (raw);
fclose (filedata);
fclose (filelog);
return 0;
}