【问题标题】:VMIN and VTIME Terminal Settings for variable sized messages可变大小消息的 VMIN 和 VTIME 终端设置
【发布时间】:2013-11-05 10:52:49
【问题描述】:

我正在尝试通过串行端口与设备交互。设备每 700 毫秒发送一次10 byte 轮询作为“心跳”。每次我阅读心跳时,我都必须回复 12 byte 长响应。

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

我目前的终端设置如下:

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 毫秒过去,但这失败了。当我希望设备在轮询间隔内发送另一条更长的消息时,这也是不够的。

是否有能够实现我想要的设置,或者我将不得不逐个字节并一次读取一个字节的数据并在单独的函数中构建消息?

【问题讨论】:

    标签: c terminal serial-port


    【解决方案1】:

    有没有办法设置串行端口,使其始终读取 一个块中的消息,不管它们的大小?

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

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

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

    【讨论】:

    • 谢谢,我设置了 VTIME = 1 和 VMIN = 255。据我了解,这将在 0.1 秒内读取缓冲区中的所有内容(最多 255 个字节)。我想我必须在之后处理缓冲区。
    • @Kells1986 - 如果您只依赖时间,而没有适当的协议,那么您以后会遇到问题,即使目前一切似乎都在您的测试环境中正常工作。
    • 您对更可靠地读取适当数量的数据有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 2019-03-11
    • 2021-10-11
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多