Find the answer to your Linux question:
Results 1 to 4 of 4
Hello, I'm writing a test application for a serial port based on an example I found on the web (sorry - the forum prohibits me pasting the URL). I'm using ...
  1. #1
    Just Joined!
    Join Date
    Jun 2009
    Posts
    20

    FIXED: Asynchronous access to serial port

    Hello,

    I'm writing a test application for a serial port based on an example I found on the web (sorry - the forum prohibits me pasting the URL). I'm using Asynchronous reception of characters using the SIGIO signal. Semi-pseudo-code looks like this:

    Code:
    static int dataAvailable = FALSE; /* file-scope variable */
    
    static void handle_sigInt(int signo) {
        dataAvailable = TRUE;
    }
    
    int main(void) {
    
        /* hook SIGINT to handle_sigInt and configure port here */
    
        while(TRUE) {
            if (dataAvailable) {
                int numBytes = 0;
                char buff[MAX];
    
                numBytes = read(fd, buff, (sizeof(buff) - 1));
    
                while (numBytes > 0) {
                    buff[numBytes] = '\0';
                    printf("%d,%s\n", numBytes, buff);
    
                    numBytes = read(fd, buff, (sizeof(buff) - 1);
                }
    
                dataAvailable = FALSE;
            }
        }
    }
    The problem I have is when the buffer is smaller than the incoming data. Suppose MAX is 4 and the incoming data is "abcdefghi\n" then I would expect the "do" loop to iteratre three times:

    Waiting...
    4:abcd
    4:efgh
    2:i
    Waiting...

    What actually happens (observed in gdb) is that the final attempt to "read" just blocks and never returns. The MAN(2) page for READ says:

    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 I expect read() to return 0 which will then terminate my while loop.

    Any ideas?
    Last edited by xyz000; 06-23-2009 at 02:56 PM. Reason: Solution found

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    I suspect that you did not open the file for non-blocking i/o, so it will block if it cannot read sizeof(buff) -1 bytes. The read() function can be either blocking or non-blocking, depending upon how the file was opened, or if the behavior has been changed with fcntl().

    From the read(2) man page:
    Code:
    ERRORS
           EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and  no  data  was
                  immediately available for reading.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Jun 2009
    Posts
    20
    Thanks Rubberman. You prompted me to read around a bit more and check a few things. I had two mistakes:

    1) I needed to make the MIN and TIME parameters both zero. I had MIN set to 1 which meant that read() was blocking until at least one character arrived.

    2) I needed to remove the ICANON flag i.e. use non-canonical processing.

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    Glad you got it figured out. My experience has been that most debugging tasks are 90% finding the root cause, and 10% or less of the time in actually fixing it.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...