尝试在 MacOS 中打开串行端口时 open(2) 函数挂起
我遇到了一个问题,当我尝试打开串行端口时,打开函数永远不会返回。这种情况不会一直发生,如果我拔下 USB 转串行适配器并将其重新插入,问题就会消失一段时间。我的代码如下所示:
fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY);
其中 bsdPath 是 /dev/cu.KeySerial1 。我尝试将 O_NONBLOCK 选项添加到 open 命令,但它仍然挂起。
我当然想了解为什么会发生这种情况。我的信念是,无论出现什么问题,指定 O_NONBLOCK 后,即使无法打开端口, open 也应该返回。如果无法打开端口,则 fileDescriptor 应为 -1 并且应设置 errno (我在调用 open 后立即检查这一点)。当然,这并没有发生。我的假设不正确吗?是否有一些已知的原因导致 open() 在遇到错误时即使指定了 O_NONBLOCK 也永远不会返回?
在 10.7.2 上使用最新版本的 Prolific PL-2303 驱动程序和基于 PL-2303 的 USB 转串行适配器,我今天能够再次重现此问题。一些注意事项:
- 当挂在
open()
调用中时,该进程不能使用 command- 中断。 (对照-C)。 - 运行
ps -avx
显示该进程的进程状态代码 U。我不确定这段代码的含义。它不会出现在通过 Google 搜索找到的ps
的手册页中。我的机器上的ps
手册页中没有列出进程状态代码。也许它特定于 Mac(10.4+?)版本的ps
? - 我注意到,在第一次出现此问题之前的运行中,我对 ioctl() 的调用将端口上的选项重置回其在我的程序中使用之前的状态,但挂起了。我不得不终止该程序(通过 Xcode 的调试器)。紧接着,在下次启动程序时,
open()
挂起...
I've run into a problem where the open function never returns when I try to open a serial port. It doesn't happen all the time, and the problem disappears for a while if I unplug my USB to serial adapter and plug it back in. My code looks like this:
fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY);
where bsdPath is /dev/cu.KeySerial1 . I've tried adding the O_NONBLOCK option to the open command, but it still hangs.
Of course I'd like to understand why this is happening. My belief is that whatever the problem, with O_NONBLOCK specified, open should return no matter what even if it was unable to open the port. If it's unable to open the port, fileDescriptor should be -1 and errno should be set (I check for this immediately after the call to open). Of course, this isn't happening. Is my assumption incorrect? Is there some known reason for open() to never return even with O_NONBLOCK specified when an error is encountered?
Using the latest version of the Prolific PL-2303 driver with a PL-2303 based USB to serial adapter on 10.7.2, I've been able to reproduce this problem again today. A few notes:
- When hung in the
open()
call, the process is not interruptible using command-. (control-C). - Running
ps -avx
shows a process state code of U for the process. I'm not sure what this code means. It doesn't appear in man pages forps
found by Googling. There is no listing of process state codes in the man page forps
on my machine. Perhaps it's specific to the Mac (10.4+?) version ofps
? - I noted that on the run immediately before the first appearance of this problem, my call to
ioctl()
to reset the options on the port back to their state before I changed them for use in my program hung. I had to kill the program (via Xcode's debugger). Immediately after this, on the next launch of the program,open()
hung...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题可能出在设备驱动程序中。您对于
O_NONBLOCK
的行为方式是正确的,但正确实现这一点取决于驱动程序。了解正在使用哪个版本的 OS X 以及哪个 USB 转串行设备会很有帮助。标准程序是确保设备直接插入 CPU USB 端口(而不是集线器)、检查电缆并检查更新的驱动程序。
另外,当 open() 阻塞时,进程是否可以被 control-c 中断?
如果您在阻塞时使用“
ps -aux
”查看进程,“STAT
”字段会显示什么?The problem is likely in the device driver. You are correct about how
O_NONBLOCK
should behave, but it is up to the driver to implement that correctly. It would be helpful to know which version OS X and which USB to Serial device is being used.Standard procedures would be to make sure the device is plugged directly into the CPU USB ports (not a hub), check cables, and check for updated drivers.
Also, when
open()
is blocking, is the process interruptible by control-c?If you look at the process with "
ps -aux
" while its blocked, what does the "STAT
" field say?