Сбой чтения из последовательного порта - PullRequest
6 голосов
/ 18 ноября 2009

У меня есть следующая программа на C:

#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

int main()
{
    int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if(fd < 0)
    {
        perror("Could not open device");
    }
    printf("Device opened\n");

    struct termios options;
    tcgetattr(fd, &options);
    cfmakeraw(&options);
    cfsetispeed(&options, B19200);
    cfsetospeed(&options, B19200);
    tcsetattr(fd, TCSANOW, &options);

    char txpacket[] = {0x23, 0x06, 0x00, 0x00, 0xdd, 0xf9};
    ssize_t written = write(fd, txpacket, sizeof(txpacket));
    printf("Written %d bytes\n", written);

    printf("Starting to wait for target to respond\n");
    while(1)
    {
        fd_set readset;
        FD_ZERO(&readset);
        FD_SET(fd, &readset);
        int nCount = select(fd + 1, &readset, NULL, NULL, NULL);
        if(nCount > 0)
        {
            if(FD_ISSET(fd, &readset))
            {
                int i;
                char buffer[128];
                ssize_t bytesread = read(fd, buffer, sizeof(buffer));
                printf("Received %d bytes\n", bytesread);
                for(i = 0; i < bytesread; i++)
                {
                    printf("  %02x", buffer[i]);
                }
            }
        }
    }
}

Эта программа открывает последовательное устройство / dev / ttyS0, записывает в него последовательность данных и начинает прослушивать ответ. Я получаю следующий вывод:

Device opened
Written 6 bytes
Starting to wait for target to respond
Received 0 bytes
Received 0 bytes
Received 0 bytes
Received 0 bytes
Received 0 bytes
Received 0 bytes
...

И приложение потребляет 100% ЦП. Я не могу получить какие-либо данные, хотя целевое оборудование фактически передает их.

Что не так?

Ответы [ 2 ]

8 голосов
/ 18 ноября 2009

read() возвращение 0 указывает на состояние конца файла. Вы должны проверить это и выйти из цикла, если это произойдет.

Относительно того, что вызывает это - конец файла на последовательном порту указывает, что он обнаружил зависание, что означает, что линия DCD была отброшена.

Вы можете установить флаг CLOCAL в options.c_cflag, чтобы игнорировать линии управления модемом, если ваше устройство не настроило их должным образом.

1 голос
/ 18 ноября 2009

Вы должны попробовать без флага O_NONBLOCK. в необработанном режиме, если настройки c_cc[VMIN] и c_cc[VTIME] равны 0, последовательный порт ведет себя так (согласно man cfmakeraw):

Если данные доступны, чтение возвращает немедленно, с меньшим из количество доступных байтов или количество запрошенных байтов. Если нет данных доступно, чтение возвращает 0

Итак, что вы должны попробовать:

options->c_cc[VMIN]=1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...