关于Windows:USB设备失败SetupComm,SetCommState,SetCommTimeouts

SetupComm, SetCommState, SetCommTimeouts fail with USB device

我正在打开USB设备:

enter

1
2
3
4
5
6
7
HANDLE hUsb = CreateFile("\\\\.\\LCLD9",
      GENERIC_READ | GENERIC_WRITE,
      0,
      null,
      OPEN_EXISTING,
      FILE_FLAG_OVERLAPPED,
      0);

呼叫成功(即hUsb不等于INVALID_HANDLE_VALUE)。但是接下来是时候对每个串行端口执行我们的操作了:

  • SetupComm(设置接收和传输缓冲区的大小)
  • SetCommState(设置流量控制,波特率等)
  • SetCommTimeouts(设置超时)

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

1
SetupComm(hUsb, 1024, 1024);

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

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

  • \\\\\\\\。\\\\\\\\ COM5
  • \\\\\\\\。\\\\\\\\ LCLD9

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

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

哪个问题更大,请问如何使用CreateFile打开USB设备后如何与它进行通信?


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

USB通信与COM端口不同。您可以将其更多地看作是外部PCI总线,而不是一条简单的"随心所欲发送数据"线路。


原来,我不必使用Comm做任何事情,因为它不是COM端口。我的WriteFile失败的原因是因为我试图写入\\\\.\\LCLD9而不是\\\\.\\LCLD9\\

后面的反斜杠非常关键;即使CreateFile都会成功返回。

1
2
3
4
5
6
7
8
9
10
11
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推断

。例如,我的极点显示器的完整设备路径为:

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

规则是检查设备路径以获取产品ID。在我的情况下,PID_A090表示它将以文件\\\\.\\LCLD9\\的形式提供。其他产品ID及其关联的文件路径:

1
2
3
4
5
Contains  DeviceName (trailing backslash is not optional)
========  ===============================================
PID_A030  \\\\.\\LCPD3\\
PID_A060  \\\\.\\LCPD6\\
PID_A090  \\\\.\\LCLD9\\

Note: Any code is released into the public domain. No attribution required.