Вопрос о вводе / выводе последовательного порта Linux - PullRequest
2 голосов
/ 04 февраля 2011

В следующей C-программе для встроенного устройства я пытаюсь отображать точку (".") Каждый раз, когда пользователь на удаленном компьютере, подключенном через последовательный кабель к моему устройству, вводит некоторые символы в своей терминальной программе и нажимает клавишу ВВОД.

Что я вижу, так это то, что после обнаружения первого возврата каретки printf отображает точки в бесконечном цикле. Я ожидал, что FD_ZERO и FD_CLR "сбросят" условие ожидания.

Как?

#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);
        }
    }
}

Ответы [ 2 ]

4 голосов
/ 04 февраля 2011

Все FD_CLR и FD_ZERO do - это сброс fd_set, он не очищает основное условие.Чтобы сделать это, вам нужно read() все данные до тех пор, пока их больше не будет.

На самом деле, если вы хотите использовать только один fd за раз, лучше отказаться отselect() в целом и просто используйте блокировку read(), чтобы увидеть, когда данные станут доступны.

На примечании стороны FD_ZERO делает то же самое, что и FD_CLR, но для всех fds.Если вы делаете одно, вам не нужно другое.

1 голос
/ 04 февраля 2011

Во-первых, используйте правильные заголовки функций, такие как int main(void). Во-вторых, FD_SET имеет верхний предел для хранения fds, иными словами, не все fds могут отслеживаться с помощью select. (poll не имеет такого ограничения.)

В-третьих, наконец, в вашем цикле вы только проверяете, есть ли данные на fd, но никогда не читаете их. Таким образом, он продолжает оставаться доступным в следующей итерации.

...