serial: flushing device buffer - am I close?

From: TJ (tj_at_getlostspammers.com)
Date: 06/24/04


Date: Thu, 24 Jun 2004 00:05:00 GMT

I'm writing a program in C that communicates with a serial device. I have a
conceptual question to clarify my interpretation of the HOWTOs...

The specs of my device, are that it responds with a fixed number of bytes
per issued command (typically 6 bytes). Sometimes, after an abend and
restart, the device's response will only be two bytes, and then my program
hangs while waiting for the remaining 4 bytes. My thought is that those
two bytes in the device's buffer are residual from the last run of the
program, assuming abnormal termination.

I changed my approach of "always wait for 6 bytes" to "read bytes until the
buffer is empty" - certainly a better approach. I also decided to flush
the buffer on the device by performing a read before any commands are
issued.

But now that I am reading the buffer until empty, it always appears to be
empty... perhaps because data has not arrived yet?? I'm sure there is a
simple technique, used millions of times, and I'm not quite finding it. My
loop will wait until data arrives, but the read() always returns zero, so
there never appears to be data. If I ignore the loop, and just ask for 6
bytes, sometimes I get all of them, sometimes I dont. Tricky.

>From the manpage on read():
On success, the number of bytes read is returned (zero indicates end of
file), and the file position is advanced by this number. It is not an error
if this number is smaller than the number of bytes requested; this may
happen for example because fewer bytes are actually available right now
(maybe because we were close to end-of-file, or because we are reading from
a pipe, or from a terminal), or because read() was interrupted by a signal.
On error, -1 is returned, and errno is set appropriately. In this case it
is left unspecified whether the file position (if any) changes.

So possibly its my configuration/code:
Linux 2.6 , GCC 3.3.3 (SuSE 9.1)

Notes:
1. I set a fixed size for 128 since my device never exceeds 72 bytes in or
out.
2. The result bytes do not always come at once, they have to be
concatenated as they arrive.

dpDevWIDGET = open(strDevWIDGET, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (dpDevWIDGET == -1){
        intUTILS_PrintMsg(7, "WIDGET", "Port not opened");
}else{
        intLRC = tcgetattr(dpDevWIDGET, &tattr);
        intLRC = cfsetispeed(&tattr, B1200);
        intLRC = cfsetospeed(&tattr, B1200);
        intLRC = tcsetattr(dpDevWIDGET, TCSAFLUSH, &tattr);
        tattr.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ISIG);
        /* reset the control characters */
        for (i=0; i<NCCS; i++) {
                tattr.c_cc[i] = _POSIX_VDISABLE;
        }
}

// expect 6 bytes, but they dont always arrive at once, so concatenate them
as they arrive from multiple reads. Use the same routine to flush the
device buffer before any commands are issued to the device that get a
response...

while(blnEOF == FALSE){
        intSize = read(dpDevWIDGET, inbuffer, 128);
        intTmpBufferTotalSize += intSize;
        if (intSize < 0){
                perror("WIDGET");
                blnEOF = TRUE;
                return(FAILURE);
                break;
        }else if (intSize == 0){
                printf("WIDGET:\tBuffer empty\n");
                blnEOF = TRUE;
                break;
        }else if (intSize > 0){
                for (intInBufferPos = 0; intInBufferPos < intSize; intInBufferPos++){
                        tmpbuffer[intTmpBufferPos++] = inbuffer[intInBufferPos];
                }
        }
}



Relevant Pages

  • Re: serial: flushing device buffer - am I close?
    ... > two bytes in the device's buffer are residual from the last run of the ... > loop will wait until data arrives, but the readalways returns zero, so ... > is left unspecified whether the file position changes. ...
    (comp.unix.programmer)
  • Re: serial: flushing device buffer - am I close?
    ... > two bytes in the device's buffer are residual from the last run of the ... > My loop will wait until data arrives, but the readalways returns zero, ... > case it is left unspecified whether the file position changes. ...
    (comp.unix.programmer)
  • Re: Data Manipulation and buffering
    ... Regarding transactions, yes, you can use them regardless of where the tables ... "Mike" wrote in message ... first col is not empty. ... with empty in the buffer for the table? ...
    (microsoft.public.fox.programmer.exchange)
  • Re: java socket i/o with callback/non-blocking
    ... | What if I need to write to the socket while it is blocked on a read? ... the reading and writing happens at the same time. ... and check if the list is empty. ... the buffer will be written when the receiving socket is ...
    (comp.lang.java.programmer)
  • Re: selfmade serial driver problem with chipset other than VIA
    ... > empty as well as when the RX buffer contains data. ... > A de facto standard way of doing this is to make a tx_sendroutine ... > of the transmit holding register and interrupt enable register> ...
    (Linux-Kernel)