-1

I am writing an application to read data from /dev/ttyUSB0. I found it necessary to call sleep before calling read in the while loop so that I get the entire line at once. Otherwise, sometimes I get part of the line and the rest in the next iteration.

Do I have to package my data with a header containing the length of the string being sent over? Or is there a better way?

    while(1) {
            usleep(10000);

            unsigned char buf[80];
            int rdlen;
            ioctl(fd, FIONREAD, &rdlen);
            if (rdlen > 0) {
                    rdlen = read(fd, buf, rdlen);
            }
            if (rdlen > 0) {
            ...     

    } 
Quaxton Hale
  • 2,460
  • 5
  • 40
  • 71
  • 2
    Poll, read whatever is in the buffer, append to result. – Eugene Sh. Dec 11 '17 at 22:28
  • 1
    Serial ports are inherently character devices. Any notion of "packet" or "line" you will have to implement yourself. – Lee Daniel Crocker Dec 11 '17 at 22:29
  • 1
    Using any sleep function will crap the performance. – Weather Vane Dec 11 '17 at 22:56
  • By *"line"* do you actually mean a line of ASCII text terminated by a '\n', or a message packet of binary data? For the former you would need to configure the serial terminal for canonical mode. See https://stackoverflow.com/questions/28682995/reading-from-serial-port-in-c-breaks-up-lines/28689567#28689567 and https://stackoverflow.com/questions/41224496/working-with-linux-serial-port-in-c-not-able-to-get-full-data/41252962#41252962 You fail to properly document your question with your initialization code. – sawdust Dec 12 '17 at 07:04
  • I meant a line of null terminated ASCII text. I will update the question with my initialization code. – Quaxton Hale Dec 12 '17 at 21:42
  • If you're receiving an ASCII NUL as the line terminator, then *termios* can be configured to treat the NUL as the EOL character. See https://stackoverflow.com/questions/36586137/stop-on-newline-when-using-read/36588517#36588517 – sawdust Dec 12 '17 at 23:43

1 Answers1

1

The better way is to simply deal with receiving partial lines, have your code reading the data figure out when you have a complete line if that is important.

something like (not tested at all):

char buffer[1000];
size_t offset = 0;
while(1 ){
int len = read(fd, buffer+offset,(unsigned)(sizeof(buffer)-offset));
if(!strchr(buffer+offset, '\n')){
/* no end-of-line */
offset +=len;
}
else
{
/* deal with complete line */
offset = 0;
}
} 
SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23