(workaround gefunden?) rs232: tcdrain wird nicht mit timeout behandelt



  • Hallo Zusammen,

    ich verwendet die tcdrain(fd); Funktion zum prüfen,
    ob die entsprechenden Zeichen auch wirklich raus sind,
    damit ich auf eine entsprechende Antwort warten kann.
    Das klappt auch prima, nur wenn ich den Fehlerfall habe,
    und zum Beispiel kein Gerät angeschlossen habe,
    wird die Funktion tcdrain() nicht beendet.

    Hier meine Settings:

    cfmakeraw(&term_attr);
    	term_attr.c_cc[VMIN] = 0; 				// finished even if no byte
    	term_attr.c_cc[VTIME] = 10; 			// 1000ms
    
    	term_attr.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IUCLC | INLCR| IXANY );
    
    	/* output modes - clear giving: no post processing such as NL to CR+NL */
    	term_attr.c_oflag &= ~(OPOST|OLCUC|ONLCR|OCRNL|ONLRET|OFDEL);
    
    	/* control modes - set 8 bit even partiy 1 stop bit*/
    	term_attr.c_cflag |= (CS8 | PARENB);
    
        /* local modes - clear giving: echoing off, canonical off (no erase with 
    	backspace, ^U,...),  no extended functions, no signal chars (^Z,^C) */
    	term_attr.c_lflag &= ~(ECHO | ECHOE | ICANON | IEXTEN | ISIG);
    
    	term_attr.c_cflag |= CRTSCTS;					// using flow control via CTS/RTS
    

    Hat jemand eine Idee ?
    Oder kann man tcdrain ersetzen durch ...

    Hier mein möglicher workaround

    /****************************************************************************/
    // Waiting until all data written to the serial port
    /****************************************************************************/
    int	mytcdrain( int	fd )
    {
    int		timeoutcounter=10;								// Timeout counter
    int		bytesToSend=1;										// Byte to send in buffer
    int		lastByteToSend=1;									// last value of send bytes in buffer
    
    	while(	timeoutcounter > 0 						// Timeout not elapsed
    					&& bytesToSend > 0)						// still bytes to send
    		{
    		ioctl(fd ,TIOCOUTQ, &bytesToSend);	// state of the buffer
    		if( lastByteToSend !=  bytesToSend)	// does the value changed
    			{
    			timeoutcounter=9;									// reset timeout transmit is running
    			lastByteToSend =  bytesToSend;		// remember the byte to transmit
    			}
    		else
    			{
    			usleep(10000);											// 10000 ysec no bytes transmit (wait)
    			timeoutcounter--;										// counting for error state (abort)
    			}
    		}
    
    	if( timeoutcounter == 0 )							// nothing transmitted
    		tcflush( fd, TCOFLUSH);								// clear transmitbuffer of system
    
    	return	( timeoutcounter != 0);					// if finished with value -> ok
    }
    

    Den muss ich aber erstmal testen. Anmerkungen sind gerne gesehen. 🙂

    Gruss Ritchie


Anmelden zum Antworten