Тайм-аут неанонического чтения () в Linux не работает - PullRequest
0 голосов
/ 21 декабря 2018

В настоящее время я пытаюсь установить связь с внешним устройством через последовательный порт, и оно работает просто отлично ... если устройство подключено.Однако, поскольку нет гарантии, что это так (и у меня есть несколько последовательных портов на выбор), было бы идеально, если бы я мог использовать синхронизированное чтение VMIN = 0 / VTIME> 0 для проверки портов (и, как правило, для предотвращения моего приложения).от блокировки на неопределенный срок, если устройство отсоединено во время работы).

Вот мой код, чтобы открыть последовательный порт и установить его в неканонический режим.Но даже если я установил VTIME на 5 (что должно быть полсекунды) и VMIN на 0 (чтобы тайм-аут начинался немедленно), read () просто блокируется на неопределенный срок, если ни одно устройство не подключено.

int32_t OpenDevice(char* device)
{
    if (access(device, R_OK | W_OK))
    {
        LOG(Log_Error, "%s() access(): %s", __func__, strerror(errno));
        goto ERR_ACCESS;
    }

    int32_t fd = open(device, O_RDWR | O_NOCTTY);

    if (fd == -1)
    {
        LOG(Log_Error, "%s() open(): %s", __func__, strerror(errno));
        goto ERR_OPEN;
    }

    struct termios tios;

    if (tcgetattr(fd, &tios))
    {
        LOG(Log_Error, "%s() tcgetattr(): %s", __func__, strerror(errno));
        goto ERR_GETATTR;
    }

    cfmakeraw(&tios);

    if (cfsetspeed(&tios, B115200))
    {
        LOG(Log_Error, "%s() cfsetspeed(): %s", __func__, strerror(errno));
        goto ERR_SETSPEED;
    }

    tios.c_cflag |= CLOCAL | CREAD;
    tios.c_cflag &= ~CRTSCTS;
    tios.c_cc[VMIN] = 0;
    tios.c_cc[VTIME] = 5;

    if (tcsetattr(fd, TCSANOW, &tios))
    {
        LOG(Log_Error, "%s() tcsetattr(): %s", __func__, strerror(errno));
        goto ERR_SETATTR;
    }

    struct termios tios_new;
    tcgetattr(fd, &tios_new);
    if (memcmp(&tios_new, &tios, sizeof(tios)))
    {
        LOG(Log_Error, "%s() failed to set attributes", __func__);
        goto ERR_SETATTR;
    }

    return fd;

ERR_SETATTR:
ERR_SETSPEED:
ERR_GETATTR:
    close(fd);
ERR_OPEN:
ERR_ACCESS:
    return -1;
}

Я не знаю, имеет ли это значение, но мое приложение работает не на ПК, а на Cyclone V SoC (от Altera / Intel) с двухъядерным процессором Cortex-A9.Используемый драйвер - это CONFIG_SERIAL_ALTERA_UART, который создает несколько устройств / dev / ttyAL.Сама ОС является версией из git-репозитория Altera, с уже включенным набором патчей PREEMPT_RT (rel_socfpga-4.1.22-ltsi-rt_16.10.02_pr).

PS: я знаю, что могу просто использовать select () иНазовите это днем, но я бы предпочел сохранить свой код простым, вместо того, чтобы добавлять кучу накладных расходов, просто чтобы получить этот тайм-аут.

Заранее спасибо за любые советы по этой проблеме.

1 Ответ

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

read () не может быть логической заменой для проверки, подключен порт или нет.Одним из решений может быть ioctl () на последовательном порту для проверки аргумента состояния модема TIOCMGET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...