5
votes

I have a usb to serial FTDI adaptor connected to my mac. I am able to use the command:

screen /dev/tty.usbserial-A601L9OC

This opens a serial terminal for the port and everything works fine. But when I try to send characters to the serial port via the command:

root# echo 'a' > /dev/tty.usbserial-A601L9OC 

the command hangs and nothing is ever sent. A similar thing happens when I try to connect to it in a c program. The program hangs trying to open the serial port:

int fd = open("/dev/tty.usbserial-A601L9OC", O_RDWR | O_NOCTTY | O_SYNC);

When I run stty on the port it prints:

root# stty -f  /dev/tty.usbserial-A601L9OC
speed 9600 baud;
lflags: -icanon -isig -iexten -echo
iflags: -icrnl -ixon -ixany -imaxbel -brkint
oflags: -opost -onlcr -oxtabs
cflags: cs8 -parenb

which looks correct. Does anybody have an ideas as to why these commands hang and never send when connecting to the serial port yet screen works just fine? Any help will be appreciated.

Update: The results of getting info from stty

bash-3.2# stty -a -f /dev/tty.usbserial-A601L9OC
speed 9600 baud; 0 rows; 0 columns;
lflags: -icanon -isig -iexten -echo -echoe -echok -echoke -echonl
-echoctl -echoprt -altwerase -noflsh -tostop -flusho -pendin
-nokerninfo -extproc
iflags: -istrip -icrnl -inlcr -igncr -ixon -ixoff -ixany -imaxbel -iutf8
-ignbrk -brkint -inpck -ignpar -parmrk
oflags: -opost -onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
stop = ^S; susp = ^Z; time = 0; werase = ^W;
2
"Hang" seems to be your favorite word that you overuse. "The program hangs trying to open the serial port" - that, if accurate, could indicate a serious kernel issue; the kernel should never hang. There's a good chance you are not correctly describing the problem. How do you determine that "nothing is ever sent'? One end of this USB-serial link is your Mac; what is at the other end?sawdust
The other end is connected to a logic analyzer where I have verified no state change on the tx line. The issue is one if software. To clarify I use the word hang to describe the behavior or a command being executed but never returning.jcb344
Could you please try stty -f /dev/tty.usbserial-A601L9OC clocal? If it does not help could you please show output of stty -a -f /dev/tty.usbserial-A601L9OC both before and during the terminal is opened in screen?pabouk
I clocal command did not seem to fix anything. Running stty -a durring the screen results in a resorce bussy message and running the comand afterwards yells:bash-3.2# stty -a -f /dev/tty.usbserial-A601L9OC speed 9600 baud; 0 rows; 0 columns; Followed by a listing of all the available flags for the device which unfortunately are to long to fit in a comment.Thanks for any help you might be able to provide.jcb344
I had a similar problem, writing a cross-platform app which would "hang" reading the port on Macosx but not on Linux machines using the same code. Furthermore if you tried to access the port again, e.g. using stty, it would run at 100% CPU, high I/O until a hard-reboot! Nothing I know of could kill the process (including sudo kill -9, nor the mac shutdown - it would also hang forever). I also could not prevent it via stty configuration. The solution (as below) was to use cu not tty.scipilot

2 Answers

5
votes

Use the device /dev/cu.usbserial-A601L9OC instead, and set the speed to 9600 baud also. Here's an example from Magnus' macrumor post:

strcpy(bsdPath, "/dev/cu.usbserial-A601L9OC");
fileDescriptor = open(bsdPath, O_RDWR);
if (-1 == fileDescriptor)
{
return EX_IOERR;
}

struct termios theTermios;
memset(&theTermios, 0, sizeof(struct termios));
cfmakeraw(&theTermios);
cfsetspeed(&theTermios, 9600);
theTermios.c_cflag = CREAD | CLOCAL;     // turn on READ and ignore modem control lines
theTermios.c_cflag |= CS8;
theTermios.c_cc[VMIN] = 0;
theTermios.c_cc[VTIME] = 10;     // 1 sec timeout
int ret = ioctl(fileDescriptor, TIOCSETA, &theTermios);

ret = read(fileDescriptor, &c, 1);
2
votes

Use O_NONBLOCK otherwise the open waits for Carrier Detect.