From owner-freebsd-questions@FreeBSD.ORG Thu Jun 22 15:28:40 2006 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B6A4C16A479 for ; Thu, 22 Jun 2006 15:28:40 +0000 (UTC) (envelope-from af300wsm@gmail.com) Received: from nz-out-0102.google.com (nz-out-0102.google.com [64.233.162.203]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8B4E043D8B for ; Thu, 22 Jun 2006 15:28:29 +0000 (GMT) (envelope-from af300wsm@gmail.com) Received: by nz-out-0102.google.com with SMTP id 18so415396nzp for ; Thu, 22 Jun 2006 08:28:29 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type; b=gV2DHUe4SHmD7Q8p+Os9I0a/VdWIohQFNgIfPD1c/fLbpvH//7Qu9UbE70WlK6rtAkH711CGJZjjTCFsqcfEEaYDrXjHOPZmdPHWFoTXJDeQFm0zLePDS0h/P5gM+G8ynEkjJwBvGHzQGmZ2xSme5ko+qbVNSH742KGjEpYFerc= Received: by 10.36.77.2 with SMTP id z2mr881471nza; Thu, 22 Jun 2006 08:28:29 -0700 (PDT) Received: by 10.36.24.10 with HTTP; Thu, 22 Jun 2006 08:28:28 -0700 (PDT) Message-ID: <340a29540606220828i500905afq6d1ff81cf095cf88@mail.gmail.com> Date: Thu, 22 Jun 2006 09:28:28 -0600 From: "Andrew Falanga" To: freebsd-questions@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Serial programming on FreeBSD 6.0 RELEASE X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jun 2006 15:28:40 -0000 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