简体   繁体   English

Linux串口问题

[英]Linux serial port woes

I am writing code to talk to another device over serial in linux 我正在编写代码以通过Linux中的串行口与另一台设备通讯

I want non-blocking with timeout even if 0 characters arrive. 我希望即使有0个字符到达也不会超时超时。 The termios struct allows you to set VTIME and VMIN, but if VMIN is larger than 0, and if 0 characters are returned, the read call will block forever...WTF, why. termios结构允许您设置VTIME和VMIN,但是如果VMIN大于0,并且返回0个字符,则读取调用将永远阻塞... WTF,为什么。 This does not seem to cover the case where the other device goes down for a short period of time and now my application is blocked on a read call. 这似乎无法解决其他设备在短时间内关闭而现在我的应用程序在读取调用中被阻止的情况。 This seems like a critical behavior to neglect. 这似乎是一种至关重要的行为,可以忽略。 I really do not want to implement my own timeouts. 我真的不想实现自己的超时。

Write command
Read block timeout of around .3s(if 0 characters, still wait max of .3s)

If you want read to return with no data after a timeout you can set MIN == 0 and TIME > 0 . 如果你想read一个超时后没有数据返回,您可以设置MIN == 0TIME > 0 From tcsetattr(3) : 来自tcsetattr(3)

MIN == 0; MIN == 0; TIME > 0: TIME specifies the limit for a timer in tenths of a second. TIME> 0:TIME以十分之一秒为单位指定计时器的限制。 The timer is started when read(2) is called. 调用read(2)时启动计时器。 read(2) returns either when at least one byte of data is available, or when the timer expires. 当至少一个字节的数据可用或计时器到期时,read(2)返回。 If the timer expires without any input becoming available, read(2) returns 0. 如果计时器到期而没有任何可用的输入,则read(2)返回0。

This mode can be used to build higher level communication functions which you must implement anyway in order to deal with partial reads (ie if the other end crashes in the middle of a "packet"), wrong packets, split packets and so on. 此模式可用于构建更高级别的通信功能,您必须始终实现这些功能,以处理部分读取(即,如果另一端在“数据包”中间崩溃),错误的数据包,拆分的数据包等。 That's all stuff which a simple read cannot do for you. 这就是简单read无法为您完成的所有工作。

Take a look at select . 看一下select It waits until data is ready to read (but doesn't actually read anything). 它等待直到数据准备好读取(但实际上不读取任何内容)。 From the man page : 手册页

timeout is an upper bound on the amount of time elapsed before select() returns. 超时select()返回之前经过的时间的上限。 It may be zero, causing select() to return immediately. 它可能为零,导致select()立即返回。 (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely. (这对轮询很有用。)如果超时为NULL(无超时),则select()可以无限期阻塞。

The code would look something like: 代码看起来像:

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;

fd_set infds;
FD_ZERO(&infds);
FD_SET(fd, &infds);

// Assume fd is the file descriptor for the serial device
if (select(fd + 1, &infds, NULL, NULL, &tv) > 0)
{
    // The read will not block now
    // Assume buffer and size are declared and set appropriately
    amountRead = read(fd, buffer, size);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM