LinuxQuestions.org

LinuxQuestions.org (http://www.linuxquestions.org/questions/index.php)
-   Linux - Hardware (http://www.linuxquestions.org/questions/forumdisplay.php?f=18)
-   -   Bash Script Freezes on exec 3</dev/ttyPIC for Serial to USB Converter (http://www.linuxquestions.org/questions/showthread.php?t=4175451340)

idoneous 02-22-2013 09:02 PM

Bash Script Freezes on exec 3</dev/ttyPIC for Serial to USB Converter
 
Hello!
I have been using an USB to Serial converter (like an FTDI ) to read output from a microcontroller. Just today, my script to output the data from the microcontroller started hanging. A few echo debug lines showed that it would hang when the exec command was executed to redirect the serial device to a file descriptor. The command used was:

exec 3</dev/ttyPIC

This command is executed after the stty command to set up the serial communications had completed successfully. The script has worked flawlessly for months. I am completely stumped. Here is a bit more about the set up.

The microcontroller writes data from a built in USART. This goes through a TTL to RS232 converted. This, in turn, is plugged in to the serial to USB. This, of course, is plugged in to the USB. On the PC side, the following udev rule gives my user and group permissions to the device:

tom@asimo:~> cat /etc/udev/rules.d/51-rs232.rules
KERNEL=="ttyUSB*", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", SYMLINK+="ttyPIC"
KERNEL=="ttyUSB*", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", OWNER:="tom" GROUP:="users"

The udev rule seems to still work. With the device plugged in, I can issue the stty command without error:
stty -F /dev/ttyPIC raw ispeed 19200 ospeed 19200 cs8 -cstopb -parenb -echo

If the device is unplugged, an input/output error is thrown as expected. If I try to assign the device to a file descriptor via:
exec 3</dev/ttyPIC, bash or the script simply hang.

I've tried the following to debug/solve. I tried unplugging/replugging, different USB ports on different hubs ( I have a few built in to the laptop ). I've logged out and back in. I've rebooted. ls /dev shows that the udev rule has set up the file for ttyPIC. lsusb shows the device has registered ( the last in the list here ):

asimo:/home/tom # lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 0cf3:3005 Atheros Communications, Inc. AR3011 Bluetooth
Bus 001 Device 004: ID 058f:b003 Alcor Micro Corp.
Bus 002 Device 003: ID 046d:c52f Logitech, Inc. Wireless Mouse M305
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

I've executed the following:
asimo:/home/tom # stty -F /dev/ttyPIC raw ispeed 19200 ospeed 19200 cs8 -cstopb -parenb -echo
asimo:/home/tom # setserial -a /dev/ttyPIC
/dev/ttyPIC, Line 0, UART: 16654, Port: 0x0000, IRQ: 0
Baud_base: 460800, close_delay: 0, divisor: 0
closing_wait: infinte
Flags: spd_normal

I usually start my script and then power on the microcontroller, so I tried the stty and exec in bash with just the serial to USB device connected. I get the same behavior. For reference, here is the script that used to work:

Code:

#!/bin/bash

cleanUp()
{
        echo ' '
        echo 'The user has ended listening on ttyUSB.'
        exec 3<&-
        exit $?
}

# Set up to trap Ctrl-C
trap cleanUp SIGINT

# Port setting
stty -F /dev/ttyPIC raw ispeed 19200 ospeed 19200 cs8 -cstopb -parenb -echo
exec 3</dev/ttyPIC

echo 'bar'

clear
echo 'Listening on ttyUSB:'

while [ 1 ]
do
        read line 0<&3

        if [ "$line" = "clear" ]
        then
                clear
                echo 'Listening on ttyUSB:'
        else
                echo $line
        fi       
done

I am running OpenSuse 12.1 on a Toshiba Qosmio laptop with Gnome 3 in Fallback mode and bumblebee for the Optimus.

tom@asimo:~> uname -a
Linux asimo.site 3.1.10-1.16-desktop #1 SMP PREEMPT Wed Jun 27 05:21:40 UTC 2012 (d016078) x86_64 x86_64 x86_64 GNU/Linux

So I read the sticky on hardware, and decided to make a test and read dmesg. I found the last few lines of dmesg. I plugged in the serial to USB converter. I executed stty and the exec commands. I unplugged the device to restore the shell. I grabbed all the new lines of dmesg. Here they are:

[ 3522.753052] usb 3-1: new full speed USB device number 8 using xhci_hcd
[ 3522.777744] xhci_hcd 0000:06:00.0: WARN: short transfer on control ep
[ 3522.780782] xhci_hcd 0000:06:00.0: WARN: short transfer on control ep
[ 3522.783772] xhci_hcd 0000:06:00.0: WARN: short transfer on control ep
[ 3522.784751] usb 3-1: New USB device found, idVendor=067b, idProduct=2303
[ 3522.784755] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 3522.784758] usb 3-1: Product: USB-Serial Controller
[ 3522.784760] usb 3-1: Manufacturer: Prolific Technology Inc.
[ 3522.786825] pl2303 3-1:1.0: pl2303 converter detected
[ 3522.814909] usb 3-1: pl2303 converter now attached to ttyUSB0
[ 3592.719389] xhci_hcd 0000:06:00.0: WARN: transfer error on endpoint
[ 3592.719432] usb 3-1: USB disconnect, device number 8
[ 3592.720038] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[ 3592.720052] pl2303 3-1:1.0: device disconnected



Thanks in advance for any advice/help you can offer!
Tom

idoneous 02-22-2013 09:18 PM

A Few More Tests That Failed
 
I tried a few more tests to isolate the problem. I executed the stty and exec commands in the shell as root. Same problem. I tried them again against the natural device file name, /dev/ttyUSB0. Still hangs on exec. I tried an exec 3</home/tom/foo.txt followed by read line 0<&3 and echo $line. It echoes the line properly.

idoneous 02-22-2013 10:50 PM

Simple Loopback Fails too
 
I tried a simple loopback. I connected the USB to Serial converter to the TTL to Serial converter and wired the TX and RX together. I powered it up on the breadboard with 5V. I executed the following.

Code:

tom@asimo:~> stty -F /dev/ttyPIC raw ispeed 19200 ospeed 19200 cs8 -cstopb -parenb -echo
stty: /dev/ttyPIC: No such file or directory
tom@asimo:~> stty -F /dev/ttyPIC raw ispeed 19200 ospeed 19200 cs8 -cstopb -parenb -echo
tom@asimo:~> while(true) do cat -A < /dev/ttyPIC; done &
[1] 23643
tom@asimo:~> echo 'foo' >/dev/ttyPIC

The first line was with the converted disconnected from the laptop. I then connected them and powered the bread board to 5V. It froze on the echo command. I think the converter is still enumerating on USB, but the serial translation fails silently. The hardware may be shot, but I don't know why.

michaelk 02-23-2013 09:24 AM

I do not recommend using bash for serial communications. I would try testing your setup by using minicom and disabling hardware flow control. Another communication application option is cutecom. It is a GUI app and can send non ASCII characters.

idoneous 02-23-2013 10:30 AM

Tried Minicom
 
I gave minicom a shot. I'm not sure if I was using it correctly. I set it up with minicom -s and saved the configuration as the default. I exited and restarted minicom. I turned echo on and sent a long string. My USB to Serial converter was connected to the RS232 converter as before. I tied RX and TX together to form a loopback. I never saw anything echo back in minicom. However, unlike sending and echo in bash, this time I did see the RX and TX LEDs flash on the RS232 converter board. Assumption now is that it can transmit but dies on reception?

michaelk 02-23-2013 11:27 AM

You can wire TX & RX on the USB serial converter itself to prove that it is working correctly. If that works then it is probably your TTL RS232 converter board. Are the LEDs tied to the input or output of the converter? Do you have an oscilloscope or digital probe to look at the TTL signals?

idoneous 02-23-2013 03:17 PM

RS232 Converter is Simple
 
The RS232 level shifter is pretty bare bones. It relies on a pair of BJT NPN and PNP transistors ( with necessary resistors, diode, and a cap ) to shift the levels. The LEDs are tied to the transistors, so each one is tied to the transmission of one party. They give no indication of reception. I can recreate a shifter with a Max232 or with basic components. Since the lights are lighting, I'm assuming the shifter is good for now.

I'll have to make a null model cable to test without the shifter. That may not be possible today. Then, I'll have to use the logic probe. Mine is very basic ( an Open Logic Sniffer from SeeedStudios ). It should be able to get a good sample at that low data rate ( 19,200 ). The software should be able to recognize the 8-n-1 pattern for me as well.

To the lab!

idoneous 02-23-2013 04:38 PM

Some Success
 
I had some success echoing with minicom, the USB to Serial, and the RS232 converter. So, I hooked the serial set up back to my microcontroller and listened with minicom. The data came through. Of course, it was unreadable in a few seconds. Not that it was incorrect; minicom simply doesn't format anything in raw echo.

My script still does not work, and freezes on exec 2</dev/ttyPIC. The firmware sends updates of sensor data ( accelerometer and pots ) every second. The script "refreshes" the screen when it sees the word "clear" and outputs everything else as it comes in. I then tried a simple inline script in bash:
while(true); do read line </dev/ttyPIC; echo $line; done

It doesn't echo any output. This is probably not hardware related then. It looks like an issue with bash or permissions.

idoneous 02-23-2013 05:07 PM

Works With Python
 
I downloaded the pyserial module. I now have a working Python program that will duplicate what I had in bash. I'm still not happy that bash is unable to read the device though. This is python 2.7 with pyserial2.6. Here's the script:

Code:

#!/usr/bin/python

import os, serial, time

s = serial.Serial('/dev/ttyPIC', 19200)
while True:
    line = s.readline()
    if "clear\n" == line:
        os.system('clear')
    else:
        print line


michaelk 02-25-2013 10:40 AM

Bash is just really poor a way of doing RS-232 communications.

idoneous 03-04-2013 05:26 PM

Marking as Solved
 
Well, I switched distros over the weekend. I'm now running Linux Mint 14 (Nadia). This seems to have fixed my bash issue. The bash script works again. I still have the python script to use as well. Since it will be impossible to push this forward, I'm going to call this resolved. Thanks to all for looking/commenting. I appreciate the help!

Tom


All times are GMT -5. The time now is 12:27 AM.