开发者

Linux serial port I/O question

开发者 https://www.devze.com 2023-02-08 19:41 出处:网络
In the following C program for an embedded device, I am trying to display a dot (\".\") every time a user, on a remote computer connected by a serial cable to my device, enters some characters on her

In the following C program for an embedded device, I am trying to display a dot (".") every time a user, on a remote computer connected by a serial cable to my device, enters some characters on her terminal program and hits the ENTER key.

What I am seeing is that once the first carriage return is detected, the printf displays dots in an infinite loop. I was expecting FD_ZERO et FD_CLR to "reset" the wait condition.

How to?

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

main()
{
    int    fd1;       /* Input sources 1 and 2 */
    fd_set readfs;    /* File descriptor set */
    int    maxfd;     /* Maximum file desciptor used */
    int    loop=1;    /* Loop while TRUE */

    /*
       open_input_source opens a device, sets the port correctly, and
       returns a file descriptor.
    */
    fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (fd1<0)
    {
        exit(0);
    }

    maxfd =fd1+1;  /* Maximum bit entry (fd) to test. */

    /*开发者_运维技巧 Loop for input */
    while (loop)
    {
        FD_SET(fd1, &readfs);  /* Set testing for source 1. */

        /* Block until input becomes available. */
        select(maxfd, &readfs, NULL, NULL, NULL);

        if (FD_ISSET(fd1, &readfs))
        {
            /* input from source 1 available */
            printf(".");
            FD_CLR(fd1, &readfs);
            FD_ZERO( &readfs);
        }
    }
}


All FD_CLR and FD_ZERO do is reset the fd_set, it doesn't clear the underlying condition. To do that, you need to read() all the data until there isn't any available anymore.

In fact, if you only want to do one fd at a time, you're better off dispensing with the select() altogether and just use a blocking read() to see when data becomes available.

On a side note, FD_ZERO does the same thing as FD_CLR, but for all the fds. If you do one, you don't need the other.


First, use proper function headers like int main(void). Second, FD_SET has an upper limit for storing fds, in other words, not all fds can be monitored with select. (poll has no such limit.)

Third and finally, in your loop, you only check whether there is data available on the fd, but you never read it. Thus, it is continuing to be available in the next iteration.

0

精彩评论

暂无评论...
验证码 换一张
取 消