James
James

Reputation: 4052

VMIN and VTIME Terminal Settings for variable sized messages

I'm trying to interface with a device via the serial port. The device sends out a 10 byte poll as a "heartbeat" every 700ms. Everytime I read the heartbeat I have to reply with a 12 byte long response.

Within this response I can request that the device sends particular data inbetween polls. The amount of data is different for different requests. Is there a way to set up the serial port such that it will always read messages in one chunk regardless of their size?

My current terminal settings are as follows:

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;
}

I've tried changing VMIN and VTIME, I thought setting VTIME = 7 would mean it would read everything in the buffer until 700ms had passed, but this fails. It would also not be sufficient for the times when I want the device to send another, longer, message inside the polling interval.

Is there a setup that would be able to achieve what I want, or am I going to have to byte the bullet and read the data one byte at a time and build the messages up in a separate function?

Upvotes: 0

Views: 1455

Answers (1)

Martin James
Martin James

Reputation: 24907

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

In general, no. Like TCP streams, serial links are byte streams and have no message-boundaries bigger than one byte.

You need a protocol that allows the messages to be parsed out of the byte stream.

That said, some serial hardware and drivers allow a 'break' signal to be sent and detected, but I don't know anyone who uses that feture any more, even if available.

Upvotes: 2

Related Questions