(solved) Linux RS232: Termios Settings für raw Datenübertragung
-
hallo Zusammen,
hat jemand Infos über die Settings von termios für eine Binary Übertragung.
Derzeit bekomme ich keine Übertragung aufgebaut, da in meinen Daten auch nicht ASC Werte vorkommen Z.B. 0x0 und Steuerzeichen wie NAK, STX, DLE.Derzeit verwende ich die Einstellungen aus dem Forum:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-39504.htmlDie Übertragung läuft hierbei mit Handshake und Checksumme.
Hat jemand eine eine Idee.
http://linux.die.net/man/3/termios kenne ich bereits. Ist jedoch teilweise sehr verwirrend, da das Geheimnis in der Kombination der Flags liegt.
so ich habe jetzt weiter an meiner Routine gearbeitet,
bekomme aber immer noch nicht die richtigen Zeichen.Ich habe ein Terminalmonitor installiert, welche die Zeichen korrekt darstellt.
Nur mein Programm zeigt Blödsinn an.Hier das setzen der Schnittstelle, wo ich den Fehler vermute:
{ if ((fd = open(TERM_DEVICE, O_RDWR | O_NOCTTY)) == -1) { perror("terminal: Can't open device " TERM_DEVICE); return(1); } /* configurare RS232 */ if (tcgetattr(fd, &term_attr) != 0) { perror("terminal: tcgetattr() failed"); return(1); } /* save old flags */ old_flags = term_attr.c_lflag; cfsetispeed(&term_attr, TERM_SPEED); cfsetospeed(&term_attr, TERM_SPEED); cfmakeraw(&term_attr); term_attr.c_cflag |= CRTSCTS; // using flow control via CTS/RTS if (tcsetattr(fd, TCSAFLUSH, &term_attr) != 0) { perror("terminal: tcsetattr() failed"); return(1); } /* change standard input */ if (tcgetattr(fd, &term_attr) != 0) { perror("terminal: tcgetattr() failed"); return(1); } if (tcsetattr(fd, TCSAFLUSH, &term_attr) != 0) perror("terminal: tcsetattr() failed"); FD_SET(fd, &input_fdset); /* Select the first channel 1 */ return 0; }
Abweichend zum Beispiel habe ich,
cfsetispeed(&term_attr, TERM_SPEED); cfsetospeed(&term_attr, TERM_SPEED); cfmakeraw(&term_attr);
zum Setzen der Flags verwendet.
Ich habe den Eindruck, das evtl. die Anzahl der Bit, Stopbits oder sowas ist. Zeitweise wird ein 3 statt eine 2 empfangen wird.Hat jemand eine Idee, wie ich der Sache Herr werde ?
Gruss
-
Hallo Zusammen,
hier die Lösung des Problems.
Der richtige Init:
if ((fd = open(TERM_DEVICE, O_RDWR | O_NOCTTY )) == -1) { perror("terminal: Can't open device " TERM_DEVICE); return(1); } /* configurare RS232 */ if (tcgetattr(fd, &term_attr) != 0) { perror("terminal: tcgetattr() failed"); return(1); } /* save old flags */ old_flags = term_attr.c_lflag; cfsetispeed(&term_attr, TERM_SPEED); cfsetospeed(&term_attr, TERM_SPEED); cfmakeraw(&term_attr); term_attr.c_cc[VMIN] = 1; // finished after one bye term_attr.c_cc[VTIME] = 8; // or 800ms time out term_attr.c_cflag |= CRTSCTS; // using flow control via CTS/RTS if (tcsetattr(fd, TCSAFLUSH, &term_attr) != 0) { perror("terminal: tcsetattr() failed"); return(1); } /* change standard input */ if (tcgetattr(STDIN_FILENO, &term_attr) != 0) { perror("terminal: tcgetattr() failed"); return(1); } if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0) perror("terminal: tcsetattr() failed"); FD_SET(fd, &input_fdset); /* Select the first channel 1 */ return 0;
Und eine andere Leseroutine, da der Read laut 'term_attr.c_cc[VMIN] = 1; ' nach jedem Zeichen beendet wird.
int tty_read(int filedesc,unsigned char *databuffer,int maxdatasize) { int state=1; int receivedbyte=0; while( state > 0 && receivedbyte < maxdatasize) { state =read(filedesc,&databuffer[receivedbyte],1); if( state > 0 ) receivedbyte++; } return receivedbyte; }
Hier waren die Fehler, O_NOCTTY fehlte:
(fd = open(TERM_DEVICE, [b]O_RDWR | O_NOCTTY[/b] ))
Falsche min. Anzahl zu lesende Zeichen und Timeout fehlten komplett
term_attr.c_cc[VMIN] = 1; // finished after one bye term_attr.c_cc[VTIME] = 8; // or 800ms time out
Dann klappt es auch mit dem Nachbarn.
Der Datentyp sollte unsigned char sein !
Gruss