gpt4 book ai didi

c# - 使用 usbser.sys 在 SerialPort.Open/DeviceIoControl/GetcommState 上卡住

转载 作者:行者123 更新时间:2023-11-30 18:41:28 25 4
gpt4 key购买 nike

我有一个 C 程序,它打开一个 COM 端口的句柄,向它写入一些字节,读出一些字节,然后关闭句柄并退出。但是,当我连续运行程序 10 次时,开始需要很长时间才能完成 GetCommState函数并卡在 SetCommState 中功能。同样的事情发生在 C# 中,一个简单的 SerialPort对象。

我能找到的唯一解决方法是将设备重新连接到端口。有没有更优雅的方法来摆脱这种卡住?可能只是一些 PC 配置错误?

更新

我重写了代码以使其使用 DeviceIoControl而不是 SetCommState。但是,这里的问题完全相同。

device = 
CreateFileW(
L"\\\\.\\COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);

static int SetBaudRate (HANDLE device) {
int error = 0;
int success = 0;
OVERLAPPED overlapped = {0};
overlapped.hEvent = CreateEvent(NULL, TRUE, 0, NULL);
if (overlapped.hEvent) {
SERIAL_BAUD_RATE baudRate = {0};
baudRate.BaudRate = SERIAL_BAUD_115200;
error =
DeviceIoControl(
device, IOCTL_SERIAL_SET_BAUD_RATE, &baudRate,
sizeof(SERIAL_BAUD_RATE), NULL, 0, NULL, &overlapped);
if (error || (!error && GetLastError() == ERROR_IO_PENDING)) {
DWORD bytes = 0;
if (GetOverlappedResult(device, &overlapped, &bytes, TRUE)) {
success = 1;
}
}
}
CloseHandle(overlapped.hEvent);
return success;
}

第一个问题:DeviceIoControl 没有立即返回(尽管是异步调用)并挂起大约两分钟。第二个问题:两分钟后它失败,错误代码为 121(ERR_SEM_TIMEOUT:“信号量超时期限已过期。”)。

  • 使用的驱动是标准的windows驱动usbser.sys
  • 知道为什么函数调用没有立即返回吗?如果没有,如何为函数设置更短的超时时间?
  • 知道函数失败的原因吗?

更新 2

也卡住的示例 C# 代码(如上面的 C 程序):

using System;
using System.IO.Ports;

sealed class Program {
static void Main (string[] args) {
int i = 0;
while (true) {
Console.WriteLine(++i);
SerialPort p =
new SerialPort("com3", 115200, Parity.None, 8, StopBits.One);
p.DtrEnable = true;
p.RtsEnable = true;
p.ParityReplace = 0;
p.WriteTimeout = 10000;
p.ReadTimeout = 3000;
try {
p.Open();
Console.WriteLine("Success!");
} catch (Exception e) {
Console.WriteLine(e.GetType().Name + ": " + e.Message);
}
p.Close();
Console.ReadLine();
}
}
}

示例输出如下:

1 (device not yet connected)
IOException: The port 'com3' does not exist.

2 (device connected but not yet in windows device manager)
IOException: The port 'com3' does not exist.

3
IOException: The port 'com3' does not exist.

4 (device connected and recognized)
Success!

5
Success!

[...] (with about one second between each enter press)

15
Success!

16 (device still connected and recognized - nothing touched! after two minutes of freeze, semaphore timeout exactly as in the C version)
IOException: The semaphore timeout period has expired.


17 (device disconnected during the two minutes of freeze. it then returns instantly)
IOException: A device attached to the system is not functioning.


18 (device still disconnected - note that the exception is a different one than the one in the beginning although it's the same case: device not connected)
IOException: The specified port does not exist.

19
IOException: The port 'com3' does not exist.

最佳答案

这是我的 c++ 类的一个工作部分,用于处理串行端口通信,稍作更改以适应 C 和您的需求。如果它不起作用,则可能是您的虚拟端口驱动程序有问题

 DCB SerialPortSettings;
HANDLE SerialPort;

int OpenPort(WCHAR* PortName,int BaudRate)
{

SerialPort = CreateFileW(PortName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);

if(SerialPort==INVALID_HANDLE_VALUE)
return -2;

RtlZeroMemory(&SerialPortSettings,sizeof(DCB));
SerialPortSettings.DCBlength = sizeof(DCB);
if(!GetCommState(SerialPort,&SerialPortSettings))
{
CloseHandle(SerialPort);
return -3;
}

//8n1 RS485
SerialPortSettings.BaudRate = BaudRate;
SerialPortSettings.ByteSize = 8;
SerialPortSettings.Parity = NOPARITY;
SerialPortSettings.StopBits = ONESTOPBIT;
SerialPortSettings.fRtsControl = RTS_CONTROL_TOGGLE;

if(!SetCommState(SerialPort,&SerialPortSettings))
{
CloseHandle(SerialPort);
return -4;
}


return 0;

}

编辑:尝试从 http://www.ftdichip.com/Drivers/VCP.htm 下载驱动程序,因为您描述的问题很可能是驱动程序或设备问题。为 Etan 工作 :)

关于c# - 使用 usbser.sys 在 SerialPort.Open/DeviceIoControl/GetcommState 上卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6749681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com