尝试在MacOS中打开串行端口时,open(2)函数挂起

尝试在MacOS中打开串行端口时,open(2)函数挂起,macos,serial-port,posix,Macos,Serial Port,Posix,我遇到了一个问题,当我试图打开串行端口时,open函数永远不会返回。它不会一直发生,如果我拔下USB到串行适配器并将其重新插入,问题会暂时消失。我的代码如下所示: fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY); 其中,bsdPath是/dev/cu.keyseria1。我已经尝试将O_NONBLOCK选项添加到open命令中,但它仍然挂起 当然,我想了解为什么会发生这种情况。我的信念是,无论出现什么问题,只要指定了O_NONBLOCK,op

我遇到了一个问题,当我试图打开串行端口时,open函数永远不会返回。它不会一直发生,如果我拔下USB到串行适配器并将其重新插入,问题会暂时消失。我的代码如下所示:

fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY);
其中,bsdPath是/dev/cu.keyseria1。我已经尝试将O_NONBLOCK选项添加到open命令中,但它仍然挂起

当然,我想了解为什么会发生这种情况。我的信念是,无论出现什么问题,只要指定了O_NONBLOCK,open都应该返回,即使它无法打开端口。如果无法打开端口,则fileDescriptor应为-1,并应设置errno(在调用open之后,我会立即检查这一点)。当然,这不会发生。我的假设不正确吗?当遇到错误时,open()即使指定了O_NONBLOCK也不会返回,这有什么已知的原因吗

在10.7.2版本中,我使用了最新版本的PL-2303驱动程序和基于PL-2303的USB到串行适配器,今天我又重现了这个问题。请注意:

  • 当挂起
    open()
    调用时,进程不能使用命令-。(对照-C)
  • 运行
    ps-avx
    显示进程的进程状态代码U。我不知道这个代码是什么意思。它不会出现在谷歌搜索到的
    ps
    手册页中。我的机器上的
    ps
    手册页中没有进程状态代码列表。也许这是特定于Mac(10.4+?)版本的
    ps
  • 我注意到,在第一次出现此问题之前的运行中,我调用
    ioctl()
    将端口上的选项重置回它们的状态,然后将它们更改为在程序中使用。我不得不(通过Xcode的调试器)终止程序。紧接着,在下一次启动程序时,
    open()
    hung

设备驱动程序中可能存在问题。关于
O_NONBLOCK
的行为方式,您是正确的,但这取决于驱动程序如何正确实现。了解使用的是哪个版本的OSX和哪个USB到串行设备会很有帮助

标准程序是确保设备直接插入CPU USB端口(不是集线器),检查电缆,并检查更新的驱动程序

另外,当
open()
阻塞时,control-c是否可以中断进程?
如果您在流程被阻止时使用“
ps-aux
”查看流程,“
STAT
”字段会显示什么?

谢谢您的回答。我在10.6和10.7上用Keyspan USA-19HS观察到了这个问题,并且有一个用户的报告和一个堆栈跟踪显示了在10.7上使用基于PL-2303的适配器时出现的相同问题。我将尝试再次复制它,以找到你的两个问题的答案。我用一些新的观察结果更新了这个问题。再次感谢。“U”表示该过程是“不可中断的”,这通常意味着它在等待设备驱动程序响应。OSX有点不寻常,因为驱动程序可以在内核之外的应用程序空间中运行。内核将
open()
ioctl()
调用传递给驱动程序,然后告诉进程等待结果。听起来驱动程序挂起了,进程挂起了(但内核是安全的)。我发现这条关于PL-2303的线索正是你在10.7 Lion上看到的。也许会有帮助:谢谢!编辑完问题后,我决定试用osx-pl2303驱动程序。我从SourceForge的原始项目页面中提取了源代码,并设法为Lion(64位)构建了它(经过一些修改)。我甚至想发布我的更新源,但我没有看到你发布的链接。无论如何,我今天还无法重现键盘平移适配器的问题,因此我认为这是多产驱动程序中的一个缺陷,解决方案是使用链接到的驱动程序,或者基于osx-pl2303代码的驱动程序。再次感谢!