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

编程入门 行业动态 更新时间:2024-10-25 06:27:48
本文介绍了无法读取串行设备拔出并重新插入连接器后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个应该读取串口设备的/ dev / ttyS0来 Linux应用程序。串行装置被以下面的方式打开:

I'm have a Linux application that is supposed to read from serial device /dev/ttyS0. The serial device is opened in the following manner:

// Open the serial port if((serial_device = open("/dev/ttyS0", O_RDWR | O_NOCTTY)) < 0){ fprintf(stderr, "ERROR: Open\n"); exit(EXIT_FAILURE); } // Get serial device attributes if(tcgetattr(serial_device,&options)){ fprintf(stderr, "ERROR: Terminal Get Attributes\n"); 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, &options)){ fprintf(stderr, "ERROR: Terminal Set Attributes\n"); exit(EXIT_FAILURE); }

我然后使用选择功能,试图从串行设备读取:

I then use the select function to try and read from the serial device:

// Flush I/O Bffer if(tcflush(serial_device,TCIOFLUSH)){ fprintf(stderr, "ERROR: I/O Flush\n"); exit(EXIT_FAILURE); } // Write message to board if(write(serial_device,msg, strlen(msg)) != (int)strlen(msg)){ fprintf(stderr, "ERROR: Write\n"); exit(EXIT_FAILURE); } switch(select(serial_device+1, &set, NULL, NULL, &timeout)){ // Error case -1: fprintf(stderr, "ERROR: Select\n"); 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; }

我试图通过确定重新打开端口如果读不成功:

I've tried reopening the port by determining if the read was not successful:

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

然而,实际拔下串行连接器的行为会导致应用程序是无法进一步读什么,并选择将只是时间做出来的。而在应用程序运行不会解决问题,并选择堵回连接器将继续检测什么。

However, the act of physically unplugging the serial connector will result in the application being unable to read anything further, and select will do nothing but time out. Plugging the connector back in while the application is running will not fix the issue, and select will continue to detect nothing.

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

The only way to successfully read from the serial port again is to restart the application. I'm wondering why this is, and how I can recover from the serial connector being unplugged at runtime.

推荐答案

使用的选择()只有一个文件描述符是不寻常的。它也增加了复杂性的水平。结果由于串行端口配置为不规范的输入,具有 VMIN 和 VTIME ,你也许可以用更简单的$ C $完成一个字符的一次读取C。例如。尝试 VMIN = 1 和 VTIME = 10 * timeout.tv_sec

The use of select() with just one file descriptor is unusual. It also adds a level of complexity. Since the serial port is configured for non-canonical input, with proper selection of VMIN and VTIME, you might be able to accomplish the read of a char at a time with simpler code. E.G. try VMIN = 1 and VTIME = 10*timeout.tv_sec

不过,你想通了,如果你愿意处理(或希望)超时,而不是等待至少一个字符到达,那么 VMIN = 0 将模拟原来的code与选择()。

However as you figured out, and if you are willing to handle (or want) a timeout rather than wait for at least one character to arrive, then VMIN = 0 will emulate your original code with the select().

VMIN = 0和VTIME> 0结果      这是一个纯粹的定时读取。如果数据在输入队列中是可用的,它传送到呼叫者的缓冲器最多为nbytes的,并立即返回给调用者。否则,驱动程序块,直到数据到达时,或者VTIME十分之一来自呼叫开始到期。如果计时器没有数据到期,返回零。单个字节足以满足该读呼叫,但如果有更多的是在输入队列中可用的,它返回给调用者。注意,这是一个整体的定时器,而不是一个字符间之一。

VMIN = 0 and VTIME > 0 This is a pure timed read. If data are available in the input queue, it's transferred to the caller's buffer up to a maximum of nbytes, and returned immediately to the caller. Otherwise the driver blocks until data arrives, or when VTIME tenths expire from the start of the call. If the timer expires without data, zero is returned. A single byte is sufficient to satisfy this read call, but if more is available in the input queue, it's returned to the caller. Note that this is an overall timer, not an intercharacter one.

但是(如OP),我百思不得其解,为什么重新连接端口连接器应该中断任何读取或选择监控,从来没有遇到过这样的问题。

However (like the OP) I'm baffled as to why reconnecting the port connector should disrupt any reads or select monitoring, and have never encountered such an issue.

更多推荐

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

本文发布于:2023-11-05 04:09:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1559859.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:连接器   设备

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!