【问题标题】:SetupComm, SetCommState, SetCommTimeouts fail with USB deviceSetupComm、SetCommState、SetCommTimeouts 因 USB 设备而失败
【发布时间】:2013-12-12 18:59:14
【问题描述】:

我正在打开一个 USB 设备:

使用CreateFile进行通信:

HANDLE hUsb = CreateFile("\\.\LCLD9",
      GENERIC_READ | GENERIC_WRITE, 
      0, 
      null, 
      OPEN_EXISTING, 
      FILE_FLAG_OVERLAPPED, 
      0);

调用成功(即 hUsb 不等于 INVALID_HANDLE_VALUE)。但接下来是时候对每个串行端口做我们所做的事情了:

每个调用都使用 1GetLastError 代码。例如:

SetupComm(hUsb, 1024, 1024);

为什么在使用“USB”串行设备时配置串行设备的操作失败,但在使用“虚拟 COM 端口”时工作? USB 设备是否不支持此类波特率、缓冲区、流量控制和超时?

如果这是通用串行设备的限制/功能,我如何检测到句柄指的是 “通用串行设备”,而不是 “COMM 端口”时间>?例如,用户是指定使用哪个端口的人:

  • \.\COM5
  • \.\LCLD9

与通用串行总线串行设备通信时失败的其他串行功能:

  • GetCommModemStatus(错误代码为 1)
  • ReadFile(错误代码为 6)
  • PurgeComm(错误代码为 6)
  • WriteFile(错误代码为 6)

这引出了一个更大的问题,一旦使用CreateFile 打开 USB 设备,您如何与它通信?

【问题讨论】:

  • 是的,您的设备可能显示为 USB 设备,但也暴露了 COM 端口。查看“端口”下的设备管理器,假设您安装了正确的驱动程序,您可能会看到与 USB 接口关联的 COM 端口。

标签: windows serial-port usb createfile


【解决方案1】:

不,USB 设备不使用这些东西。如果您的设备是实际的 USB-to-RS232(或其他慢速串口),那么您应该打开与之关联的 COM 端口。让驱动程序处理发送该数据的工作。

USB 通信与 COM 端口不同。您可以将其视为外部 PCI 总线,而不是简单的 send-whatever-data-you-wan 线路。

【讨论】:

  • 那么如何与 USB 设备通信呢? CreateFile? WriteFile?, ReadFile?
  • @IanBoyd 您使用驱动程序。您如何使用该驱动程序取决于设备类型和驱动程序。
【解决方案2】:

原来我不需要对Comm 做任何事情,因为它不是 COM 端口。我的WriteFile 失败的原因是我试图写信给\\.\LCLD9 而不是\\.\LCLD9\

结尾的反斜杠很关键;即使CreateFile 双向返回成功。

void WriteToDisplay(String s)
{
   //Open the display
   var hLineDisplay = CreateFile("\\.\LCLD9\", GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);

   //Write the command
   DWORD bytesWritten;
   WriteFile(hLineDisplay, s, s.Length, ref bytesWritten, nil);

   FileClose(hLineDisplay);
}

任何使用 Logic Controls LD9000 USB Line Display 的人,以上是您写入显示器的方式。

在对他们的 .NET Line Display 驱动程序进行逆向工程后,我还会提到您使用的端口的名称,例如:

  • \\.\LCLD9\
  • \\.\LCPD6\
  • \\.\LCPD3\

可以从使用 Windows 安装程序 API 返回的完整 devicePath 推断出来。比如我的极显设备全路径是:

\\?\USB#VID_0FA8&PID_A090#6&DF2EE03&0&1#{A5DCBF10-6530-11D2-901F-00C04FB951ED}
                 \______/
                    |
                ProductID

规则是检查产品 ID 的设备路径。在我的情况下PID_A090 意味着它将作为文件\\.\LCLD9\ 提供。其他产品 ID 及其相关文件路径:

Contains  DeviceName (trailing backslash is not optional)
========  ===============================================
PID_A030  \\.\LCPD3\
PID_A060  \\.\LCPD6\
PID_A090  \\.\LCLD9\

注意:任何代码都会发布到公共领域。无需署名。

【讨论】:

  • 我和你有同样的问题。可以获取devicePath,但是不明白你从哪里找到DeviceName(\\.\LCLD9)的信息?
  • @lads 我查看了他们的 .NET 驱动程序的源代码。最后还是要转身调用原生的Win32 api函数。我只是将他们的源代码用作文档。
猜你喜欢
  • 2018-11-16
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 2018-02-16
相关资源
最近更新 更多