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

拔下并重新插入连接器后无法从串行设备读取

我有一个Linux应用程序,应该从串行设备/dev/ttyS0读取。 串行设备以下列方式打开:

// Open the serial port if((serial_device = open("/dev/ttyS0",O_RDWR | O_NOCTTY)) < 0){ fprintf(stderr,"ERROR: Openn"); exit(EXIT_FAILURE); } // Get serial device attributes if(tcgetattr(serial_device,&options)){ fprintf(stderr,"ERROR: Terminal Get Attributesn"); exit(EXIT_FAILURE); } cfsetspeed(&options,speed); // Set I/O baud rates cfmakeraw(&options); // Set options to transceive raw data options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode options.c_cflag &= ~CSTOPB; // 1 stop bit options.c_cflag &= ~CRTSCTS; // disable hardware flow control options.c_cc[VMIN] = 1; // Minimum number of characters to read options.c_cc[VTIME] = 10; // One second timeout // Set the new serial device attributes if(tcsetattr(serial_device,TCSANow,"ERROR: Terminal Set Attributesn"); exit(EXIT_FAILURE); }

然后我使用selectfunction尝试从串口设备读取:

// Flush I/O Bffer if(tcflush(serial_device,TCIOFLUSH)){ fprintf(stderr,"ERROR: I/O Flushn"); exit(EXIT_FAILURE); } // Write message to board if(write(serial_device,msg,strlen(msg)) != (int)strlen(msg)){ fprintf(stderr,"ERROR: Writen"); exit(EXIT_FAILURE); } switch(select(serial_device+1,&set,NULL,&timeout)){ // Error case -1: fprintf(stderr,"ERROR: Selectn"); exit(EXIT_FAILURE); // Timeout case 0: success = false; break; // Input ready default: // Try to read a character switch(read(serial_device,&c,1)){ // Error (miss) case -1: success = false; break; // Got a character default: msg[i++] = c; break; } break; } // Set 200ms timeout this->timeout.tv_sec = 0; this->timeout.tv_usec = 200000; }

我已经尝试通过确定读取是否不成功重新打开端口:

if(!success) close(serial_device); openPort(); // Same as above }

但是,物理拔出串行连接器的行为将导致应用程序无法再读取任何内容,并且select只会超时。 在应用程序运行时插入连接器将无法解决问题,select将继续检测到任何内容

无法使用串行电缆debugging内核驱动程序

通过改变握手线来使串口通知

检测字符设备是否在Linux中与termios api(c ++)断开连接

C ++通过COM口进行通讯

串口C ++问题

再次成功读取串口的唯一方法是重新启动应用程序。 我想知道为什么这是,以及如何我可以从串行连接器被拔出运行时恢复。

有关串口和编程的综合信息?

模拟串口

Linux串行读取抛出错误

用C / C ++和LibSerial在Ubuntu上读写串口

Linux – 串口读取返回EAGAIN

使用select()只有一个文件描述符是不寻常的。 这也增加了复杂性。

由于串行端口被配置为非规范输入,通过正确选择VMIN和VTIME ,您可以使用简单的代码一次完成字符的读取。 EG尝试VMIN = 1和VTIME = 10*timeout.tv_sec

然而,正如你所想的那样,如果你愿意处理(或者想要)一个超时而不是等待至少一个字符到达,那么VMIN = 0将会用select()来模拟你的原始代码

VMIN = 0,VTIME> 0

这是一个纯粹的定时读取。 如果数据在输入队列中可用,则将其传送到主叫方的缓冲区,最大为nbytes,并立即返回给主叫方。 否则,驱动程序阻塞,直到数据到达,或者VTIME十分之一从通话开始到期。 如果定时器没有数据到期,则返回零。 单个字节足以满足这个读取调用,但是如果输入队列中有更多的可用字段,则返回给调用者。 请注意,这是一个整体计时器,而不是一个字符。

然而(像OP)我很困惑,为什么重新连接端口连接器应该会中断任何读取或选择监视,并且从来没有遇到过这样的问题。

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

相关推荐