Опрос последовательного порта не работает на Beaglebone Black

Я просто не могу заставить функцию poll() реагировать на данные, отправляемые через UART1 / /dev/ttyO1. Закодируйте следующим образом, может быть, кто-нибудь заметит мою глупую ошибку?

#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>

int openPort()
{
    struct termios oldtio, newtio;

    int fd = open("/dev/ttyO1",O_RDWR|O_NOCTTY|O_NONBLOCK|O_NDELAY);
    if (fd == -1)
    {
        printf( "could not open tty" );
        return -1;
    }

    if ( tcgetattr( fd, &oldtio ) == -1 )
    {
        printf( "error getting tcattr\n" );
        close( fd );
        return -1;
    }

    cfmakeraw( &newtio );
    cfsetispeed( &newtio, B9600 );
    cfsetospeed( &newtio, B9600 );
    newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8 | B9600;
    newtio.c_cflag |= (CLOCAL | CREAD);
    newtio.c_cflag &= ~(PARENB | PARODD);
    newtio.c_cflag &= ~CRTSCTS;
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_iflag = 0;//IGNPAR;
    //newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
    newtio.c_lflag = 0;
    newtio.c_oflag = 0;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 1;
    tcflush( fd, TCIOFLUSH );
    if ( tcsetattr( fd, TCSANOW, &newtio ) == -1 )
    {
        close( fd );
        printf( "error setting attrs\n" );
        return -1;
    }

    return fd;
}

void selectLoop( int fd )
{
    struct pollfd fds[1];
    fds[0].fd = fd;
    fds[0].events = POLLIN;

    int rc = poll( fds, 1, 100000 );
    if (rc < 0)
    {
        perror( "poll" );
    }
    else if (rc > 0)
    {
        char buffer[32] = {0};
        int r = read( fd, buffer, sizeof(buffer) );
        if (r == -1)
        {
            printf( "error: %s\n", strerror( errno ) );
        }
        else
        {
            printf( buffer );
        }
    }
    else
    {
        printf( "No data\n" );
    }
    //close( fd );
    sleep( 1 );
}

int main( int c, char ** v )
{
    int fd = openPort();
    if (fd >= 0)
    {
        while(1)
        {
            selectLoop(fd);
        }
    }

    return 0;
}

Я получаю тот же результат, используя select(). Однако, если я присоединяю сигнал к «полученным данным», сигнал срабатывает, хотя я пытаюсь избежать этого сценария, поскольку он вызывает хаос в среде отладки Netbeans.

К вашему сведению: версия платы B6, UART1 подключается только через TX/RX. Программа "экран" успешно принимает и отправляет символы с UART, так что я знаю, что она принципиально работает.


person Julian Gold    schedule 24.09.2014    source источник
comment
Вы забыли сказать нам, в чем проблема. Какой результат вы получаете? Что вы ожидаете?   -  person David Schwartz    schedule 24.09.2014
comment
Я запускаю терминал (Hypertrm) на своем ПК-разработчике и ввожу в него символы. Он подключен на скорости 9600 бод, без четности, 1 стоповый бит, 8-битные символы, без аппаратного управления. Экранная программа на моем BBB воспроизводит символы, которые я печатаю, поэтому я надеюсь, что моя программа также будет отображать символы, которые я печатаю, на своем ПК-терминале. Я ничего не получаю - метод poll() просто блокируется, без ошибок, просто не видит никаких входных данных от UART.   -  person Julian Gold    schedule 24.09.2014
comment
В openport() newtio используется до его инициализации. Вам нужно что-то вроде newtio = oldtio; между tcgetattr() и cfmakeraw(). Прочитайте Правильная настройка режимов терминала и Руководство по последовательному программированию для операционных систем POSIX   -  person sawdust    schedule 24.09.2014
comment
Хороший совет, @sawdust - но результат идентичен. Нет повторяющихся символов.   -  person Julian Gold    schedule 24.09.2014
comment
Правильно, мы установили кабель FTDI через концентратор на BBB и открыли последовательное соединение с ним на /dev/ttyUSB0 - результат был эхо-символами! Гипотеза: сигнал доступности данных ввода-вывода не был настроен (правильно) на /dev/ttyO1 - ошибка ядра/накидки/железа?   -  person Julian Gold    schedule 24.09.2014
comment
Однако теперь программа печатает только каждый второй введенный символ?   -  person Julian Gold    schedule 24.09.2014
comment
Я заменил бит выбора на while( read(...) > 0 ) {...} и о чудо, я получаю правильно эхо-строки. Кажется, это говорит о том, что select() и poll() не работают в Angstrom Linux на BBB, поэтому мне было бы очень интересно узнать, заставил ли кто-нибудь их работать!   -  person Julian Gold    schedule 24.09.2014


Ответы (1)


Замените это чем-нибудь разумным:

        printf( buffer );

Возможно:

for (int i = 0; i < r; ++i)
   putchar(buffer[i]);
fflush(stdout);

Это сбрасывает и не рискует напечатать больше символов, чем будет прочитано, если буфер заполнен.

person David Schwartz    schedule 24.09.2014
comment
Хорошая идея. Тот же результат - ничего не напечатано. - person Julian Gold; 24.09.2014
comment
poll вернулся? Возможно, вы просто получаете непечатаемые символы. - person David Schwartz; 24.09.2014
comment
Не вернулся, Дэвид. - person Julian Gold; 24.09.2014