Serial programming on FreeBSD 6.0 RELEASE

Derek Ragona derek at computinginnovations.com
Thu Jun 22 17:02:04 UTC 2006


Andy,

Did you kill the getty running on the port?

Are you getting any errors?

         -Derek

At 10:28 AM 6/22/2006, Andrew Falanga wrote:
>Hello,
>
>I've got a case where I'm writing a simply serial program to send bytes from
>one system to another over a serial cable.  The program works in Linux, but
>when I use it in FreeBSD nothing happens.  The program starts and, in the
>case of receiving, waits for data to appear on the /dev/cuad1 port and times
>out in select.  If I'm sending in FreeBSD, the send program believes it has
>written all the data but nothing is received in Linux (either with running
>my code on Linux or using kermit).  On FreeBSD, however, if I use kermit to
>monitor the /dev/cuad1 port and send, using my code, from Linux, all 2500
>packets are transmitted ok.  Also, when sending from Linux and receiving in
>FreeBSD, the FreeBSD machine show silo and tty-level interrupt errors.  The
>man page for sio describes that as problems in the interrupt handler, for
>silo overflows, and that data arrived faster than the application could
>process (for the tty-level overflows).
>
>What am I doing wrong?  What is it that Kermit does to allow data being read
>from the /dev/cuad1 device that I'm not?  I've been looking over the kermit
>sources but to be honest, before Thursday of last week, I'd never programmed
>for serial ports before let alone having any knowledge of termios.
>Therefore, I'm looking at a very steep learning curve.  Please look over my
>ctor for the serial line class that is in my code.  After much debugging,
>I'm convinced that my problem is in how I'm configuring my port.
>
>sline::sline( std::string d, int opm ) : dev( d ), opMode( opm )
>{
>   memset( &oldSettings, 0, sizeof( oldSettings ) );
>   memset( &ioPort, 0, sizeof( ioPort ) );
>   memset( recvBuf, 0, PACKETSIZE );
>   memset( &timeout, 0, sizeof( timeout ) );
>
>   FD_ZERO( &incoming );
>
>   timeout.tv_sec = TIMEOUT_SEC;
>   timeout.tv_usec = TIMEOUT_USEC;
>
>   // create the packet
>   char asciiPrtChars = 32; // first printable ascii character in decimal
>   for( int i = 0; i < PACKETSIZE; i++ ) {
>      packet[i] = asciiPrtChars++;
>      if( asciiPrtChars == 127 ) // 127 is the delete character
>         asciiPrtChars = 32;
>   }
>
>   // on the systems this code was meant to compile, LINUX and FreeBSD
>   // O_NDELAY and O_NONBLOCK are the same, however, this is not always
>   // true
>   fd = open( dev.c_str(), O_RDWR | O_NOCTTY | O_NDELAY );
>   if( fd < 0 )
>      throw init();
>
>   tcgetattr( fd, &oldSettings );
>   tcgetattr( fd, &ioPort );
>
>#ifdef DEBUG
>   COUT << "Current input speed is " << cfgetispeed( &ioPort ) << ENDL;
>   COUT << "Current output speed is " << cfgetospeed( &ioPort ) << ENDL;
>#endif
>
>#if 0
>   if( opMode == OPMODE_WRITE ) {
>      if( fcntl( fd, F_SETFL, 0 ) < 0 ) {
>         perror( "fcntl" );
>         throw init();
>      }
>   } else {
>      if( fcntl( fd, F_SETFL, FNDELAY ) < 0 ) {
>         perror( "fcntl" );
>         throw init();
>      }
>      FD_SET( fd, &incoming );
>   }
>#endif
>
>#if 0
>   // configure control field, this should configure for 8N1
>   // first, disable flow control (may have to put it back in)
>   // ioPort.c_cflag &= ~CRTSCTS;
>   ioPort.c_cflag |= CRTSCTS | CLOCAL | CREAD;
>   ioPort.c_cflag &= ~PARENB;
>   ioPort.c_cflag &= ~CSTOPB;
>   ioPort.c_cflag &= ~CSIZE;
>   ioPort.c_cflag |= CS8;
>
>   // configure local field, setting to RAW mode
>   ioPort.c_lflag |= ~( ICANON | ECHO | ECHOE | ISIG );
>
>   // configure the input field, setting to ignore parity errors
>   // and disable software flow control
>   ioPort.c_iflag |= IGNPAR;
>   ioPort.c_iflag &= ~( IXON | IXOFF | IXANY );
>
>   // configure output field, setting to RAW
>   ioPort.c_iflag &= ~OPOST;
>#endif /* end of if 0 */
>
>   // configure for raw data transfer
>   cfmakeraw( &ioPort );
>
>   // set VMIN and VTIME parameters in c_cc array
>   ioPort.c_cc[VMIN] = PACKETSIZE;
>   ioPort.c_cc[VTIME] = 0;
>
>   if( cfsetispeed( &ioPort, BAUDRATE ) < 0 ) {
>      perror( "cfsetispeed" );
>      throw init();
>   }
>
>   if( cfsetospeed( &ioPort, BAUDRATE ) < 0 ) {
>      perror( "cfsetospeed" );
>      throw init();
>   }
>
>   COUT << "flushing dev: " << dev << ENDL;
>   if( tcflush( fd, TCIOFLUSH ) < 0 ) {
>      perror( "tcflush" );
>      throw init();
>   }
>
>   COUT << "Setting new parameters to: " << dev << ENDL;
>   if( tcsetattr( fd, TCSANOW, &ioPort ) < 0 ) {
>      perror( "tcsetattr" );
>      throw init();
>   }
>
>#if 0
>   if( ioctl( fd, TIOCMGET, &portStatus ) < 0 ) {
>      perror( "ioctl - get" );
>      throw init();
>   }
>
>   // I believe we want to clearn the DCD bit
>   portStatus &= ~TIOCM_DTR;
>
>   if( ioctl( fd, TIOCMSET, &portStatus ) < 0 ) {
>      perror( "ioctl - set" );
>      throw init();
>   }
>#endif /* removed for debugging, still not sure I need it */
>
>   if( fcntl( fd, F_SETFL, FNDELAY | O_NONBLOCK ) < 0 ) {
>      perror( "fcntl" );
>      throw init();
>   }
>
>#ifdef DEBUG
>   COUT << "New input speed is " << cfgetispeed( &ioPort ) << ENDL;
>   COUT << "New output speed is " << cfgetospeed( &ioPort ) << ENDL;
>#endif
>} // end of sline ctor
>
>Thanks for you help,
>Andy
>_______________________________________________
>freebsd-questions at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-questions
>To unsubscribe, send any mail to "freebsd-questions-unsubscribe at freebsd.org"
>
>--
>This message has been scanned for viruses and
>dangerous content by MailScanner, and is
>believed to be clean.
>MailScanner thanks transtec Computers for their support.
>

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
MailScanner thanks transtec Computers for their support.



More information about the freebsd-questions mailing list