(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.html

    Die Ü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


Anmelden zum Antworten