Как я могу очистить состояние select () после достижения тайм-аута в C ++ на Raspberry PI 3 - PullRequest
0 голосов
/ 06 декабря 2018

В настоящее время я работаю на Raspberry PI 3. Для зацикливания связи через последовательный порт я подключил TXD к RXD через порт GPIO.Итак, я получаю байты, которые я только что отправил.В моей программе мне нужно использовать ограничение тайм-аута для чтения порта.Для этого я использовал следующую команду select(fd + 1, &read_fds, NULL, NULL, &timeout).Если время ожидания соответствует первому байту (то есть я ничего не отправил), я не могу прочитать следующий байт - состояние чтения все еще "Тайм-аут".

Мой вопрос: как я могу очистить это состояние или что я должен установить для параметров порта, чтобы получить второй байт, который был отправлен после истечения времени ожидания во время предыдущего чтения порта.Мой код ниже:

#include <stdio.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/select.h>

int main ()
{
    struct termios RSopt;
    char byte = 0;
    char str[2] = {0,0};
    int fd;
    fd = open( "/dev/ttyS0", O_RDWR| O_NOCTTY );

    // Parameters setting for serial communication
    tcgetattr(fd, &RSopt);
    cfsetospeed (&RSopt, (speed_t)B300);
    cfsetispeed (&RSopt, (speed_t)B300);
    RSopt.c_cflag &= ~CSIZE;  // Mask out size
    RSopt.c_cflag |= CS8;     // Or in 7-bits
    RSopt.c_cflag |= PARODD;  // Enable Parity - even by default
    tcsetattr (fd, TCSANOW, &RSopt);   // Set new options

    // Timeout setting
    struct timeval timeout;
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;
    // File descriptor initialization
    fd_set read_fds;

    //-----------------------------------------------------------------
    FD_ZERO(&read_fds);
    FD_SET(fd, &read_fds);
    str[0] = 0xFA;
    //write(fd, str, 1);
    //printf("Send.\n");
    //printf("Wait...\n");

    if (select(fd + 1, &read_fds, NULL, NULL, &timeout) == 1) {
        read(fd, &byte, 1);
        printf("Recive: %x\n", byte);
    } else {
        printf("Timeout.\n");
    }

    //-----------------------------------------------------------------
    FD_ZERO(&read_fds);
    FD_SET(fd, &read_fds);
    str[0] = 0xFB;
    write(fd, str, 1);
    printf("Send.\n");
    printf("Wait...\n");

    if (select(fd + 1, &read_fds, NULL, NULL, &timeout) == 1) {
        read(fd, &byte, 1);
        printf("Recive: %x\n", byte);
    } else {
        printf("Timeout.\n");
    }
}

1 Ответ

0 голосов
/ 06 декабря 2018

Вам необходимо установить

timeout.tv_sec = 2;
timeout.tv_usec = 0;   

перед каждым select, так как некоторые ядра будут уменьшать ваш timeout со временем, потраченным на select, оставляя вам нулевое значение времени ожидания, если вы 'мы уже истекли один раз.

Редактировать: Вы можете подтвердить, что это то, что происходит с вами, напечатав значения timeout до select, который истекает напрямую.

...