Question

We've been bashing our heads off of this one all morning. We've got some serial lines setup between an embedded linux device and an Ubuntu box. Our reads are getting screwed up because our code usually returns two (sometimes more, sometimes exactly one) message reads instead of one message read per actual message sent.

Here is the code that opens the serial port. InterCharTime is set to 4.

void COMClass::openPort()
{
  struct termios tio;

  this->fd = -1;

  int tmpFD;

  tempFD = open( port, O_RDWR | O_NOCTTY);
  if (tempFD < 0)
  {

    cerr<< "the port is not opened"<< port <<"\n";
    portOpen = 0;
    return;
  }


  tio.c_cflag = BaudRate | CS8 | CLOCAL | CREAD ;
  tio.c_oflag = 0;
  tio.c_iflag = IGNPAR;    
  newtio.c_cc[VTIME]    = InterCharTime;
  newtio.c_cc[VMIN]     = readBufferSize;  
  newtio.c_lflag = 0;      

  tcflush(tempFD, TCIFLUSH);
  tcsetattr(tempFD,TCSANOW,&tio);

  this->fd = tempFD;
  portOpen = true;
}

The other end is configured similarly for communication, and has one small section of particular iterest:

while (1)
{
    sprintf(out, "\r\nHello world %lu", ++ulCount);
    puts(out);
    WritePort((BYTE *)out, strlen(out)+1);
    sleep(2);
} //while

Now, when I run a read thread on the receiving machine, "hello world" is usually broken up over a couple messages. Here is some sample output:

1: Hello
2: world 1
3: Hello
4: world 2
5: Hello
6: world 3

where number followed by a colon is one message recieved. Can you see any error we are making?

Thank you.

Edit: For clarity, please view section 3.2 of the Linux Serial Programming HOWTO. To my understanding, with a VTIME of a couple seconds (meaning vtime is set anywhere between 10 and 50, trial-and-error), and a VMIN of 1, there should be no reason that the message is broken up over two separate messages.

Was it helpful?

Solution

I don't see why you are surprised.

You are asking for at least one byte. If your read() is asking for more, which seems probable since you are surprised you aren't getting the whole string in a single read, it can get whatever data is available up to the read() size. But all the data isn't available in a single read so your string is chopped up between reads.

In this scenario the timer doesn't really matter. The timer won't be set until at least one byte is available. But you have set the minimum at 1. So it just returns whatever number of bytes ( >= 1) are available up to read() size bytes.

OTHER TIPS

If you are still experiencing this problem (realizing the question is old), and your code is accurate, you are setting your VTIME and VMIN in the newtio struct, and the rest of the other parameters in the tio struct.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top