функция open не возвращается для последовательного порта - PullRequest
1 голос
/ 14 марта 2019

У меня есть модуль последовательного порта USB, и я хочу использовать его в своем приложении C.Проблема в том, что системный вызов open не возвращается!

int serialDevice = open ("/ dev / ttyUSB0", O_RDWR | O_NOCTTY);// не возвращает

Я добавил своего пользователя в группу dialout, и я могу получить доступ к порту без root-доступа, используя minicom в терминале.Так что это не проблема разрешения.Даже если это так, он должен немедленно вернуться и выдать ошибку разрешения.Но функция открытия вообще не возвращается.

Что мне делать?У вас есть идеи?

Спасибо

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

int serialDevice = open ("/ dev / ttyUSB0", O_RDWR | O_NOCTTY);

В дополнение к ответу @ darune и O_NONBLOCK, вы также можете рассмотреть O_SYNC,См. Также Как открывать, читать и записывать с последовательного порта в C?

Вы также можете рассмотреть вопрос об исключении дескриптора файла, чтобы другая программа, такая как Modem Manager, не открывала устройство и гадость с твоим состоянием .Исключительно хорошо из-за O_RDWR.См. Также Как сделать / dev / ttyACM0 (и друзей) эксклюзивным? в списке рассылки Kernel Newbies.

Чтобы сделать дескриптор файла эксклюзивным, вам нужно использовать ioctl и TIOCEXCL.O_EXCL не работает должным образом, потому что это не учитывается для символьных устройств (а люди ядра говорят -ENOPATCH).

int term_config(int fd, int speed)
{
    struct termios tty;
    memset(&tty, 0, sizeof(tty));

    if (tcgetattr(fd, &tty) != 0) {
        log_error("term_config: tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfmakeraw(&tty);
    tty.c_cflag |= CLOCAL;   /* ignore status lines   */
    tty.c_cflag |= CRTSCTS;  /* hardware flow control */

    cfsetospeed(&tty,(speed_t)speed);
    cfsetispeed(&tty,(speed_t)speed);

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        log_error("term_config: tcsetattr: %s\n", strerror(errno));
        return -1;
    }

    if (ioctl(fd, TIOCEXCL, NULL) != 0) {
        log_error("term_config: ioctl_tty: %s\n", strerror(errno));
        return -1;
    }

    return 0;
}

Вы бы назвали term_config что-то вроде:

int serialDevice = open("/dev/ttyUSB0", ...);
if (serialDevice == -1) { /* error */ }

int result = term_config(serialDevice, B115200);
if (result != 0) { /* error */ }
2 голосов
/ 14 марта 2019

Я полагаю, это может произойти, если устройство занято и т. Д.

Вам необходимо добавить флаг O_NONBLOCK :

O_NONBLOCK При открытииFIFO с установленным O_RDONLY или O_WRONLY: * Если установлен O_NONBLOCK, open () только для чтения должен возвращаться без задержки.Функция open () только для записи должна возвращать ошибку, если ни один процесс в настоящее время не имеет файла, открытого для чтения.* Если O_NONBLOCK очищен, метод open () только для чтения должен блокировать вызывающий поток, пока поток не откроет файл для записи.Функция open () только для записи должна блокировать вызывающий поток, пока поток не откроет файл для чтения.

При открытии блока открывается специальный или символьный специальный файл, который поддерживает неблокирование:

*
    If O_NONBLOCK is set, the open() function shall return without blocking for the device to be ready or available. Subsequent behavior

устройства зависит от устройства.* Если O_NONBLOCK очищен, функция open () должна блокировать вызывающий поток, пока устройство не будет готово или доступно до возврата.

В противном случае поведение O_NONBLOCK не определено.

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