使用termios api(c++)在Linux中检测字符设备是否已断开连接
我在Linux中使用termios api与串行设备通信。我正在尝试检测设备是否已断开连接,以便在超时后尝试重新连接。我有以下示例代码:使用termios api(c++)在Linux中检测字符设备是否已断开连接,c++,linux,serial-port,termios,C++,Linux,Serial Port,Termios,我在Linux中使用termios api与串行设备通信。我正在尝试检测设备是否已断开连接,以便在超时后尝试重新连接。我有以下示例代码: while(1) { FD_ZERO(&rfds); FD_SET(tty_fd, &rfds); // have tried checking fcntl(tty_fd, F_GETFL); too // Blocking call to wait until we have data select
while(1)
{
FD_ZERO(&rfds);
FD_SET(tty_fd, &rfds);
// have tried checking fcntl(tty_fd, F_GETFL); too
// Blocking call to wait until we have data
select(tty_fd+1, &rfds, NULL, NULL, NULL);
// While we have data, collect it
while (read(tty_fd, &c, 1)>0 && bytesRead++<200)
{
serialBuffer.push_back(c);
}
bytesRead = 0;
// Try to parse it
BufferParse();
}
在ttyUSB设备物理断开连接后,我实际上没有看到select或fcntl返回错误值-1。当然,我可以检查/dev/中的文件是否存在,但我希望有一个更优雅的解决方案
非常感谢您的建议,谢谢 首先值得一提的是,串行usb的行为如下: 在usb设备上,未拔出的断开连接被称为 @断开连接:当接口不再可访问时调用,通常为 因为其设备已经或正在断开,或者 正在卸载驱动程序模块 在我们的例子中,它是usb_串行_断开连接usb_接口*接口 它叫usb_串行_控制台_断开串行,它叫tty_挂断。。。等等 您可以从这里开始执行以下操作: 简言之,这将导致以下经典方式: pselect表示文件描述符已就绪,ioctlfd、FIONREAD和len返回零len 就是这样,你拔下了设备的插头 从代码派生的求和:
while(1)
{
FD_ZERO(&rfds);
FD_SET(tty_fd, &rfds);
// have tried checking fcntl(tty_fd, F_GETFL); too
// Blocking call to wait until we have data
int ready = select(tty_fd + 1, &rfds, NULL, NULL, NULL);
if(ready && FD_ISSET(tty_fd, &rfds)) {
size_t len = 0;
ioctl(tty_fd, FIONREAD, &len);
errsv = errno;
if(len == 0)
{
printf("prog_name: zero read from the device: %s.", strerror(errsv));
/* close fd and cleanup or reconnect etc...*/
exit(EXIT_FAILURE);
}
// While we have data, collect it
while (read(tty_fd, &c, 1)>0 && bytesRead++<200)
{
serialBuffer.push_back(c);
}
bytesRead = 0;
// Try to parse it
BufferParse();
}
}
很遗憾,你没有说你正在使用什么样的设备
如果您的设备能够进行RTS/CTS流量控制,也可以检测线路中断。使用USB适配器,可能会有两种断开级别。当设备连接到串行端口时,该设备无法再通信。RS232链路本身可能会断开连接。DSR/DTR信号通常用于确定本地连接。如果图中还有USB,USB适配器可以与主机断开连接。因此,您需要澄清您试图检测的内容。读取数据将来自连接的串行设备,而不是串行端口或USB适配器。如果设备是调制解调器,则您有另一个连接链接。在这种情况下,我特别指的是USB到串行设备与主机断开连接。您可以使用libudev通过文件描述符查看设备事件:我认为您还应该为select设置EXPEPTFDS参数4。只要套接字本身未关闭并且只能由程序关闭,select就不会得到-1。除了ExceptFD之外,您可能还应该获得ReadFD的指示,并且在尝试读取时,您应该在那里得到错误以及EIO或类似的错误。正如sawdust所发布的,有许多类型的断开连接。我过去有过一个案例,我无法确定串行链接是否由于简单的原因丢失,比如电缆断裂。我最终使用串行心跳并在超时线程上检测它。这是一个更安全的解决方案,因为在某些情况下termios可能不会发出信号。嘿,谢谢你的详细评论!该设备是一个FTDI芯片连接到树莓Pi。拉斯皮安·杰西,如果发行版重要的话。稍后我会尝试一下,并更新它的工作原理。Np,实际上,零读取来自于用虚拟的ops处理程序替换默认的ops处理程序,虚拟的ops处理程序在读取时返回零。这与套接字的行为几乎相同。