0

I am developing a software wherein I have to receive data via serial port. I am opening the port in canonical mode and setting the VEOL flag to 0X78(hexadecimal). The problem I am facing is that read is exiting every time it receives byte value 0X0A in between. Can somebody help me in resolving this issue, I want read to block till I receive end byte as 0X78. This is the code I have written so far

struct termios tio;
char buf[255];

int fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); 
if (fd <0) {
    perror(MODEMDEVICE);
    exit(−1); 
}

bzero(&tio, sizeof(tio));
tio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
tio.c_iflag = IGNPAR;
tio.c_oflag = 0;
tio.c_lflag = 1;
tio.c_cc[VEOL] = 0X78;

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


int read=read(fd,buf,255);

printf("Number of bytes read is %d\n",read);

Thank you in advance.

CherryDT
  • 25,571
  • 5
  • 49
  • 74
Harry
  • 2,177
  • 1
  • 19
  • 33
  • 1
    Did you try not sending newlines on the other side? – Ignacio Vazquez-Abrams May 19 '16 at 11:58
  • 1
    It's probably not intended to be newlines but part of a binary data stream, otherwise the OP could have just used newlines as terminators in the first place. – CherryDT May 19 '16 at 12:00
  • Thanks for the reply. Actually 0x0A is part of the data that I'm receiving. So I want to know if its possible to block read till last byte comes as 0X78 – Harry May 19 '16 at 12:05
  • 1
    Looks to me like you can not use canonical mode for binary data http://man7.org/linux/man-pages/man3/tcsetattr.3.html – Richard Chambers May 19 '16 at 12:07
  • You can't use the built-in "read until newline" mechanism then - instead, read one character at a time and append it to your buffer, and stop when you encounter your termination character. – CherryDT May 19 '16 at 12:07
  • 1
    Take a look at the sample in [how to open, read, and write from serial port in C](http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c/6947758#6947758) which has canonical turned off. You still will need to process the byte stream to determine the end of a set. You might do this by reading one byte at a time or by implementing your own buffering. Or perhaps the device will only send the necessary number of characters so you just need to read until no more bytes come in? – Richard Chambers May 19 '16 at 12:21
  • Certainly, some drivers have the ability to have a single trigger character set. If this is not exposed to the OS, or the OS does nto expose it to the user processes, then.. ;( Alternatively, write your app on Windows, where the DCB does expose an 'EvtChar': https://msdn.microsoft.com/en-us/library/windows/desktop/aa363214%28v=vs.85%29.aspx – Martin James May 19 '16 at 12:25
  • *"tio.c_lflag = 1"* -- That's really bad coding. See [Setting Terminal Modes Properly](http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html#SEC237). As @RichardChambers already suggested, you shouldn't be using canonical mode for reading binary data (but he pointed you to a poor example). The EOL characters must be unique in your character set for text. If you use noncanonical mode, then you could ***escape*** the intermediate 0x78s, but that means that the sender has to do the escaping, and you need to write a parser at the receive end. – sawdust May 19 '16 at 17:40

1 Answers1

0

The manual page states:

VEOL (0, NUL) Additional end-of-line character (EOL). Recognized when ICANON is set.

So, it doesn't replace all end-of-line characters, it just adds one more, meaning 0xa is still active.

Don't send the wrong data, or filter them out in software.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Thanks for the reply. Actually 0x0A is part of the data that I'm receiving. So I want to know if its possible to block read till last byte comes as 0X78 – Harry May 19 '16 at 12:06