06-21-06 06:32 AM
Hello,
As the subject suggests, I'm a newbie to serial programming. Prior to
last week Thursday, I'd never done serial programming before at all.
So, what I've learned is all from the Posix Guide to Serial Programming
at http://www.easysw.com/~mike/serial/serial.html. (Oh, also the
Serial-programming howto, but I found out from a regular in this group
(comp.unix.programmer) that, that howto is woefully innaccurate.)
Ok, I'm going off of memory because the code is at work. I have a
class which serves as a "one-stop-shop" for my send and receive sides.
(Ok, this program is simple in concept. I want to send on one side and
receive on the other. That's it. It's not a bidirectional data
exchange.) When I compile my code on Linux, I can execute ok using a
NULL-MODEM cable between two serial ports on the same box. When I
connect the Linux machine to my FreeBSD machine, the code times out if
the receive side is run on FreeBSD. (Also, new development, after
reading through the POSIX serial programming guide, the FreeBSD machine
now comes back with silo errors and such. I read in the man page for
sio(4) that these errors are generated by interrupts. Any help
isolating that problem would be greatly appreciated.)
I'll write the class initialization here because I think it's in there
that I'm having problems. The send/receive class members use write()
and read() respectively. In the receive member method, I use select on
the file descriptor opened in the ctor.
sline::sline( std::string d, int op ) : dev( d ), opMode( op )
{
memset( &ioPort, 0, sizeof( struct termios ) );
char frstAsciiPrtChar = 32;
for( int i =0; i < PACKETSIZE; i++ ) {
packet[i] = frstAsciiPrtChar++;
if( frstAsciiPrtChar == 127 )
frstAsciiPrtChar = 32; // don't want the delete character
in the packet
}
if( fd = open( dev.c_str(), O_RDWT | O_NOCTTY | O_NONBLOCKING ) < 0
) {
perror( "open" );
throw init();
}
fcntl(fd, F_SETFL, 0);
tcgetattr( fd, &ioPort );
// setup c_cc array
ioPort[VMIN] = PACKETSIZE; // this is 255
ioPort[VTIME] = 0;
// setup c_cflag for 8N1 as in the guide and setup hardware flow
control
ioPort.c_cflag &= ~PARENB
ioPort.c_cflag &= ~CSTOPB
ioPort.c_cflag &= ~CSIZE;
ioPort.c_cflag |= CS8;
ioPort.c_cflag |= CRTSCTS;
// setup c_lflag for non canonical raw mode
ioPort.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// setup c_iflag to ignore parity since we're in 8N1
ioPort.c_iflag |= IGNPAR;
// setup c_oflag for RAW mode
ioPort.c_oflag &= ~OPOST;
// set baud to 115200 from MACRO
cfsetispeed(&ioPort, B115200);
cfsetospeed(&ioPort, B115200);
tcsetattr(fd, TCSANOW, &ioPort);
} // end of ctor
The only thing that is actually missing in this from my memory is the
calls I make to add the file descriptor to the FD_SET for select when
reading data from the port on the receiving end.
On Linux, it seems to work. However, my code eventually times out
waiting for data roughly after 1250 packets have been received. On
FreeBSD, if I tell it to receive from the Linux machine, it just times
out on the select call and then errors out saying there's no data on
the port. If I tell it to send on FreeBSD, it says that it sends all
2500 packets ok, but then on Linux, no packets are received and same
story.
I suspect there's something with configuration between the two OS's
that's blocking this from working, but because I'm so new to serial
programming, I'm not sure what to look for. Any help is greatly
appreciated.
Thanks for the time and sorry for the long post.
Andy
[ Post a follow-up to this message ]
|