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