【问题标题】:Serial Port Hangs串口挂起
【发布时间】:2013-09-16 06:42:58
【问题描述】:

我有一个连接到我的 mac 的 USB 到串行 FTDI 适配器。我可以使用命令:

screen /dev/tty.usbserial-A601L9OC

这将为端口打开一个串行终端,一切正常。但是当我尝试通过命令向串口发送字符时:

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

命令挂起,没有发送任何内容。当我尝试在 c 程序中连接到它时,也会发生类似的事情。程序在尝试打开串口时挂起:

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

当我在它打印的端口上运行 stty 时:

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

这看起来是正确的。有没有人知道为什么这些命令在连接到串行端口时挂起并且从不发送但屏幕工作得很好?任何帮助将不胜感激。

更新:从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;

【问题讨论】:

  • “Hang” 似乎是你最喜欢用的词。 “程序挂起尝试打开串行端口” - 如果准确,可能表明存在严重的内核问题;内核不应该挂起。您很有可能没有正确描述问题。您如何确定“从未发送任何内容”?此 USB 串行链接的一端是您的 Mac;另一端是什么?
  • 另一端连接到逻辑分析仪,我已验证 tx 线路上没有状态变化。问题是软件之一。为了澄清,我使用挂起这个词来描述正在执行但从未返回的行为或命令。
  • 你能试试stty -f /dev/tty.usbserial-A601L9OC clocal吗?如果没有帮助,请在screen 打开终端之前和期间显示stty -a -f /dev/tty.usbserial-A601L9OC 的输出?
  • 我的 clocal 命令似乎没有解决任何问题。在屏幕上运行 stty -a 会产生一条资源繁忙的消息,然后运行命令大喊:bash-3.2# stty -a -f /dev/tty.usbserial-A601L9OC speed 9600 baud; 0 rows; 0 columns; 后面是设备的所有可用标志的列表,不幸的是,这些标志太长了,无法放入评论中。感谢您的帮助你也许可以提供。
  • 我遇到了类似的问题,编写了一个跨平台的应用程序,它会在 Macosx 上“挂起”读取端口,但在使用相同代码的 Linux 机器上却不行。此外,如果您尝试再次访问该端口,例如使用 stty,它将以 100% CPU、高 I/O 运行,直到硬重启!我所知道的一切都无法终止该进程(包括 sudo kill -9,也没有 mac 关机 - 它也会永远挂起)。我也无法通过 stty 配置阻止它。解决方案(如下)是使用 cu 而不是 tty。

标签: macos unix serial-port posix ftdi


【解决方案1】:

改用设备/dev/cu.usbserial-A601L9OC,并将速度也设置为9600波特。以下是来自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);

【讨论】:

  • This page 讨论cu.*tty.* 之间的区别
  • 谢谢@grebneke,很高兴知道有什么区别,我引用了:The technical difference is that /dev/tty.* devices will wait (or listen) for DCD (data-carrier-detect), eg, someone calling in, before responding. /dev/cu.* devices do not assert DCD, so they will always connect (respond or succeed) immediately.
  • 感谢这对我有帮助。
【解决方案2】:

使用 O_NONBLOCK 否则打开等待载波检测。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 2018-12-09
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    相关资源
    最近更新 更多