c - 可变大小消息的 VMIN 和 VTIME 终端设置

标签 c terminal serial-port

我正在尝试通过串口连接设备。设备每 700 毫秒发送一次 10 字节 轮询作为“心跳”。每次我读取心跳时,我都必须回复一个 12 字节 长的响应。

在此响应中,我可以请求设备在轮询之间发送特定数据。不同的请求,数据量是不同的。有没有一种方法可以设置串行端口,使其始终以一个 block 的形式读取消息,而不管它们的大小?

我目前的终端设置如下:

int ttySetRaw(int fd, struct termios *prevTermios)
{
    struct termios t;
    if (tcgetattr(fd, &t) == -1)
        return -1;

    if (prevTermios != NULL)
        *prevTermios = t;

    t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
    t.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON | PARMRK);
    t.c_oflag &= ~OPOST; /* Disable all output processing */
    t.c_cc[VMIN] = 12; /* 12 chars at a time, enough for the poll and the reply to be sent/received in one chunk, when I change this I no longer receive the poll*/
    t.c_cc[VTIME] = 10; /* maximum timeout 1 second */

    t.c_cflag |= PARENB;
    t.c_cflag |= PARODD;

    if (tcsetattr(fd, TCSAFLUSH, &t) == -1)
       return -1;

    return 0;
}

我试过更改 VMIN 和 VTIME,我认为设置 VTIME = 7 意味着它会读取缓冲区中的所有内容,直到 700 毫秒过去,但这失败了。当我希望设备在轮询间隔内发送另一条更长的消息时,这也不够。

是否有能够实现我想要的设置,或者我是否必须硬着头皮一次读取一个字节的数据并在单独的函数中构建消息?

最佳答案

Is there a way to set up the serial port such that it will always read messages in one chunk regardless of their size?

一般来说,不会。与 TCP 流一样,串行链接是字节流,没有大于一个字节的消息边界。

您需要一个允许从字节流中解析消息的协议(protocol)。

就是说,一些串行硬件和驱动程序允许发送和检测“中断”信号,但我不知道有人会再使用该功能,即使可以使用也是如此。

关于c - 可变大小消息的 VMIN 和 VTIME 终端设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19787265/

相关文章:

c++ - 从 C/C++ 代码执行 RDMSR 和 WRMSR 指令

c - 终端未运行 C

javascript - 如何在 macos Catalina 上永久安装 NVM?

c - 如何在 DOS/C 中访问非标准 COM 端口(USB->Serial,COM5+)?

java - 是否可以在没有连接设备的情况下写入串行端口?

将int转换为一定大小的二进制字符串

c - 如果我必须打印大量斐波那契数列,为什么我的打印斐波那契数列代码不起作用?

linux - 嵌入式linux串行终端多路复用器

c - 为什么 "else"没有被执行?

http - Curl 说它无法解析主机,但可以解析主机