C# 使用usbser.sys冻结SerialPort.Open/DeviceIoControl/GetcommState

C# 使用usbser.sys冻结SerialPort.Open/DeviceIoControl/GetcommState,c#,c,serial-port,freeze,deviceiocontrol,C#,C,Serial Port,Freeze,Deviceiocontrol,我有一个C程序,它打开COM端口的句柄,向其中写入一些字节,读取一些字节,然后关闭句柄并退出。然而,当我连续10次运行这个程序时,它开始花费很长时间来完成这个函数,并陷入函数中。同样的事情也发生在C#中的一个简单对象上 我能找到的唯一修复方法是将设备重新连接到端口。有没有更优雅的方法来摆脱这种冻结?这可能只是一些电脑配置错误吗 更新 我已经重写了代码,使其能够使用,而不是SetCommState。然而,这里的问题完全相同 device = CreateFileW( L"

我有一个C程序,它打开COM端口的句柄,向其中写入一些字节,读取一些字节,然后关闭句柄并退出。然而,当我连续10次运行这个程序时,它开始花费很长时间来完成这个函数,并陷入函数中。同样的事情也发生在C#中的一个简单对象上

我能找到的唯一修复方法是将设备重新连接到端口。有没有更优雅的方法来摆脱这种冻结?这可能只是一些电脑配置错误吗

更新

我已经重写了代码,使其能够使用,而不是
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程序):

示例输出如下所示:

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;

}

编辑:尝试从下载驱动程序,因为您描述的问题很可能是驱动程序或设备问题。为Etan工作:)

当你说它“冻结系统”时,“系统”只是你的程序还是你的整个计算机?只是程序。当我使用调试器逐步检查代码时,GetCommState会在大约1分钟后返回,SetCommState会花费更长的时间,直到由于超时而失败。这是内置串行端口、虚拟端口、USB串行端口还是其他什么?选项为“内置”或“USB”。什么是“内置USB”COM端口?等等,你的电脑主板上有USB到串行转换器?什么?我使用windows附带的标准驱动程序将usb设备连接到虚拟com端口。问题不在于它根本不工作,而只是有时——例如多次打开和关闭串行端口时。我还将在问题中添加一个简单的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;

}