微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Windows USB虚拟Com端口识别断开连接事件

我正在使用虚拟串行端口设备驱动程序与USB设备通信的应用程序。 我们遇到了这样的情况:如果在串口手柄打开的情况下,设备被拔出(或者崩溃),那么在串口手柄closures后重新连接的唯一方法是拔下设备然后重新插入。

如果我能够快速检测到故障,则有潜在的解决方法。 问题是,在这些情况下,下列函数调用不报告错误:ClearCommError(),GetCommModemStatus()和ReadFile()。 根据我的经验,拔出设备时返回错误的唯一函数是WriteFile()。 可以理解的是,我并不想写无意义的数据来testing端口连接是否仍然有效。

我的问题是,是否有一些方法可以用来确定端口连接是否仍然有效。

如果有任何问题,我在做什么,下面的代码片段显示了我的端口轮询线程正在做什么:

通过TCP创build一个虚拟串行端口连接

WriteFile如何在不写入任何数据的情况下成功?

batch file:从串口接收数据并将其写入到txt-File中

是否有可能以编程方式更改USB < – >串行转换器的“BM”延迟选项?

串行通信通过IOCP

// set up the communications timeouts COMMTIMEOUTS timeouts; if(!GetCommTimeouts(port_handle,&timeouts)) throw OsException(my_strings[strid_get_comm_timeouts_Failed].c_str()); timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; timeouts.ReadTotalTimeoutConstant = 10; timeouts.WritetotalTimeoutMultiplier = 0; timeouts.WritetotalTimeoutConstant = 10000; if(!SetCommTimeouts(port_handle,&timeouts)) throw OsException(my_strings[strid_set_comm_timeouts_Failed].c_str()); on_open(); // we need to set a base for the carrier detect signal. This will be used to determine // when the signal "changes" while the loop executes bool carrier_detect_set = false; uint4 modem_status = 0; if(!GetCommModemStatus(port_handle,&modem_status)) throw OsException(my_strings[strid_get_modem_status_Failed].c_str()); if(modem_status & MS_RLSD_ON) carrier_detect_set = true; // we are Now ready to enter the main service loop for this thread. OVERLAPPED io_control; memset(&io_control,sizeof(io_control)); while(!should_close) { // we need to check to see if any comm errors have occurred uint4 comm_errors = 0; if(!ClearCommError(port_handle,&comm_errors,0)) throw OsException(my_strings[strid_clear_comm_errors_Failed].c_str()); if(comm_errors != 0) on_comm_errors(comm_errors); // we also need to determine if the carrier detect line has changed modem_status = 0; if(!GetCommModemStatus(port_handle,&modem_status)) throw OsException(my_strings[strid_get_modem_status_Failed].c_str()); if(carrier_detect_set && (modem_status & MS_RLSD_ON) == 0) on_carrier_detect_change(false); else if(!carrier_detect_set && (modem_status & MS_RLSD_ON) != 0) on_carrier_detect_change(true); // we will Now execute any command that might be waiting command_handle command; commands_protector.lock(); while(!commands.empty()) { command = commands.front(); commands.pop_front(); commands_protector.unlock(); command->execute(this,port_handle,false); commands_protector.lock(); } commands_protector.unlock(); // Now we will try to write anything that is pending in the write queue fill_write_buffer(tx_queue); while(!tx_queue.empty() && !should_close) { uint4 bytes_avail = tx_queue.copy(tx_buff,sizeof(tx_buff)); uint4 bytes_written = 0; rcd = WriteFile( port_handle,tx_buff,bytes_avail,&bytes_written,&io_control); if(!rcd || bytes_written == 0) throw Csi::OsException(my_strings[strid_write_Failed].c_str()); if(rcd) { SetLastError(0); if(bytes_written) { tx_queue.pop(bytes_written); on_low_level_write(tx_buff,bytes_written); } if(bytes_written < bytes_avail) throw OsException(my_strings[strid_write_timed_out].c_str()); } } // we will Now poll to see if there is any data available to be written uint4 bytes_read = 0; rcd = ReadFile( port_handle,rx_buff,sizeof(rx_buff),&bytes_read,&io_control); if(rcd && bytes_read) on_low_level_read(rx_buff,bytes_read); else if(!rcd) throw OsException(my_strings[strid_read_Failed].c_str()); }

在使用重叠I / O时,我遇到了同样的问题。

从USB串口设备读取二进制stream

如何获得VCOM设备的USBstring描述符(Windows)?

Windows中的javax.comm.properties的替代位置

是否可以通过串口通过PuTTY发送文本文件内容

将串口守护进程+ PHP移植到Windows

我可以通过添加以下代码来检测端口故障:

while(!should_close) { // we will attempt to get and then set the comm state each time the loop repeats. // This will hopefully allow use to verify that the port is still valid. if(tx_queue.empty()) { DCB dcb; init_dcb(&dcb); if(!GetCommState(port_handle,&dcb)) throw OsException(my_strings[strid_get_modem_status_Failed].c_str()); if(!SetCommState(port_handle,&dcb)) throw OsException(my_strings[strid_get_modem_status_Failed].c_str()); }

我担心在每个轮询循环上做这个测试的开销。 我可能会尝试将这与RegisterDeviceNotification()按照MSalters建议。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐