Forum: PC-Programmierung Datenverlust beim Lesen von serieller USB-Schnittstelle


von Zonk79 (Gast)


Lesenswert?

Hi,

ich habe ein sehr dubioses Problem beim Lesen von Daten von einer 
seriellen Schnittstelle. Die Gegenstelle ist ein kleines Embedded-Gerät, 
welches per USB-CDC angebunden ist. Unter Windows taucht das Gerät als 
COMx auf und lesen/schreiben von Daten ist kein Problem.

Unter Linux (verschiedene Distris probiert), taucht das Gerät als 
/dev/ttyACMx auf und sich sehe beim Lesen von diesem Gerät immer mal den 
Verlust von ein, zwei Bytes an Daten. Beim Senden scheint das nicht zu 
passieren.

Man kann mit dem Gerät auch per TCP/IP kommunizieren. Hier kommt das 
geiche Protokoll zum Einsatz und auf clientseite der gleiche Code. Da 
hier (wie unter Windows) ebenfalls kein Problem auftritt, würde ich 
einen Fehler in meiner Implementierung ausschließen.

Ich habe bisher noch keinerlei Regel erkennen können, wie/wann/wo der 
Verlust der Daten passiert, deswegen ist mir jeder Hinweis, jede 
Spekulation und jede Idee willkommen!

Der Code zum Öffnen der seriellen Schnittstelle sieht übrigens so aus:
1
struct termios       options;
2
struct serial_struct sStruct;
3
 
4
*fd= open(serialParams->port, O_RDWR|O_NOCTTY);// | O_NDELAY);
5
if (*fd == -1) return ERROR_DEVICE;
6
fcntl(*fd, F_SETFL,FNDELAY);
7
 
8
tcgetattr(*fd, &options);
9
 
10
//Enable the receiver and set local mode
11
options.c_cflag |= (CLOCAL | CREAD);
12
 
13
options.c_cflag &= ~CSIZE; // Mask the character size bits
14
options.c_cflag |= CS8;
15
 
16
options.c_cflag &= ~(PARENB|PARODD);
17
 
18
options.c_cflag&=~CSTOPB;
19
 
20
options.c_lflag=0;
21
options.c_iflag=0;
22
options.c_oflag=0;
23
 
24
options.c_iflag |= (IXON | IXOFF | IXANY);
25
options.c_cflag &= ~CRTSCTS;
26
 
27
ioctl(*fd, TIOCGSERIAL, &sStruct);
28
sStruct.flags &= ~ASYNC_SPD_MASK;
29
ioctl(*fd, TIOCSSERIAL, &sStruct);
30
 
31
speed=1000000;
32
 
33
ioctl(*fd, TIOCGSERIAL, &sStruct);
34
sStruct.flags = (sStruct.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
35
sStruct.custom_divisor = (sStruct.baud_base + (speed / 2)) / speed;
36
ioctl(*fd, TIOCSSERIAL, &sStruct);
37
 
38
cfsetispeed(&options, B38400);
39
cfsetospeed(&options, B38400);
40
 
41
if (tcsetattr(*fd, TCSANOW, &options)!=0) return ERROR_DEVICE;

von Peter II (Gast)


Lesenswert?

suche mal in Forum. Es gab schon mal ein Fall wo es wirklich ein Bug im 
Linuxtreiber gab.

habe ich Spontan jetzt nicht gefunden.

von Daniel A. (daniel-a)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.