3

from this I copied the example for serial port configuration:

tcgetattr (serialfd, &tty);

cfsetospeed(&tty,B115200);
cfsetispeed(&tty,B115200);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
tty.c_iflag &= ~IGNBRK;
tty.c_lflag = 0;

tty.c_oflag = 0;
tty.c_cc[VMIN]  = 0;
tty.c_cc[VTIME] = 5;

tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag |= 0;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;

My actual code is like this:

char buf[100];
write(serialfd, "PING", strlen("PING"));
fsync(serialfd);

while (1) 
{
    read(serialfd, buf, sizeof(buf));
    printf("length: %d\n", strlen(buf));
}

In this case it is printing length: 6 infinitely without stopping. when I change tty.c_cc[VMIN] = 1 and tty.c_cc[VTIME] = 0 it doesn't read.(it blocks in read())

I'm using debian 6.0.5 with usb to serial converter. I open serial port like this:

serialfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_SYNC);
Community
  • 1
  • 1
Majid Azimi
  • 5,575
  • 13
  • 64
  • 113

1 Answers1

2

Look at your code

while (1) 
{
    read(serialfd, buf, sizeof(buf));
    printf("length: %d\n", strlen(buf));
}

You have written a packet prior to this loop, then on the first iteration you read the available data which gets read into your buffer. You need to either memset your buffer to zeros each time OR zero terminate your buffer using the read byte count given in the return value of your call to read. You then loop infinitely, each time reading again - but subsequent reads will not copy any more data as there is none to read. However, your buffer remains unchanged by the call to read therefore and your printed output remains the same every iteration as the buffer remains the same every iteration.

As for the blocking aspect, you should read the following guide (which has been recommended on SO before and is very good as an introduction to serial port programming)

http://www.easysw.com/~mike/serial/serial.html

This section describes the behaviour you get when setting VMIN and VTIME to various values. In particular the last paragraph explains the blocking behaviour you see.

VMIN specifies the minimum number of characters to read. If it is set to 0, then the VTIME value specifies the time to wait for every character read. Note that this does not mean that a read call for N bytes will wait for N characters to come in. Rather, the timeout will apply to the first character and the read call will return the number of characters immediately available (up to the number you request).

If VMIN is non-zero, VTIME specifies the time to wait for the first character read. If a character is read within the time given, any read will block (wait) until all VMIN characters are read. That is, once the first character is read, the serial interface driver expects to receive an entire packet of characters (VMIN bytes total). If no character is read within the time allowed, then the call to read returns 0. This method allows you to tell the serial driver you need exactly N bytes and any read call will return 0 or N bytes. However, the timeout only applies to the first character read, so if for some reason the driver misses one character inside the N byte packet then the read call could block forever waiting for additional input characters.

VTIME specifies the amount of time to wait for incoming characters in tenths of seconds. If VTIME is set to 0 (the default), reads will block (wait) indefinitely unless the NDELAY option is set on the port with open or fcntl.

mathematician1975
  • 21,161
  • 6
  • 59
  • 101