[Xastir] USB to RS-232 issue

ka7o ka7o at ka7o.net
Sat Apr 30 21:16:38 EDT 2011


Yup, PL2303 is correct. However, it seems it might not be a 'bug' per 
se. Seems it's becoming a larger problem. See below. FWIW, the 
'workaround' didn't work for me here.

I'll test here by going back a few revs in kernel - see what happens.

73


2011-04-25: 	#12

I was hit with this problem using my GPS tracking application on a 
2.6.38 Kernel. After much researching it seems this is NOT a driver bug 
but a CHANGE in the kernel Serial API semantics.

What has happened is that the API now blocks when a Serial device is not 
indicating it is ready. This included 'open' on a serial device which 
now can block.

Since lots of RS232 serial devices do not bother with any control 
signals such as DCD (data carrier detect) they never indicate they are 
ready and open blocks. This is the 'HANG' we are seeing, There are 
several workarounds:

1. Wire the RS232 "DCD" signal correctly. This is often not an option. 
In my case I am reading from a GPS mouse which has a built in RS232 to 
USB convertor.

2. Open the serial device non-blocking and set the CLOCAL flag on the 
device. From the tty_ioctl documentation:

Marking a line as local

If the CLOCAL flag for a line is off, the hardware carrier detect (DCD) 
signal is significant, and an open(2) of the corresponding tty will 
block until DCD is asserted, unless the O_NONBLOCK flag is given. If 
CLOCAL is set, the line behaves as if DCD is always asserted. The 
software carrier flag is usually turned on for local devices, and is off 
for lines with modems.

In my code I open and explicitly set CLOCAL

     qDebug ( devPath );
     file = open(devPath.ascii(), O_RDONLY | O_NONBLOCK);
     if ( file != -1 ) {
         // serial port needs to be setup
         struct termios term;
         bool ok = tcgetattr ( file, &term ) == 0;
         cfmakeraw ( &term );
         term.c_iflag |= CLOCAL;
         cfsetispeed( &term, B4800 );
         ok &= tcsetattr ( file, TCSAFLUSH, &term ) == 0;
       ....

Sadly after you 'open' a device non-blocking you cannot change it back 
to blocking. The simplist solution is to use a 'poll' before you 'read' 
to wait for new data to arrive.

         // read byte from non blocking file
         pollfd pfd;
         pfd.fd = file;
         pfd.events = POLLIN;
         int ok = poll( &pfd, 1, -1 );
         if ( ok < 0 ) {
              // poll failed
         }
         char buf[1];
         ssize_t ch = read( file, buf, 1 );
         if ( ch < 1 ) {
              // read error

3. A third alternative, which I have not tried, is to use "stty" to set 
the serial device CLOCAL before your application starts.

Hopefully this help clear up the issue. I would recommend setting this 
bugs status to INVALID. Possibly the perceived regression on the USB 
serial drivers could be resolved in that they default to being CLOCAL 
which is what I assume was the case before. But another change to the 
Kernal semantics would probably just confuse the issue!


On 04/30/2011 06:52 PM, Jason KG4WSV wrote:
> There's a bug in the PL2303 driver introduced in the latest kernel. Google the correct name (I think it's PL2303) and linux bug and you should get details and a workaround.
>
> -Jason
>
> _______________________________________________
> Xastir mailing list
> Xastir at lists.xastir.org
> http://lists.xastir.org/cgi-bin/mailman/listinfo/xastir




More information about the Xastir mailing list