Почему open () никогда не возвращается? - PullRequest
0 голосов
/ 24 апреля 2020

Я работаю в среде Fedora, используя код c, чтобы открыть порт USB для связи с последовательным устройством.

По большей части моя программа работает нормально. Однако, как часть тестирования, я регулярно открываю окно терминала и запускаю экранную команду, а затем вручную отправляю команды на последовательное устройство. Это также хорошо работает, но после этого порт больше не доступен для программы c. Я закрыл экземпляр экрана либо с помощью ctrl-a k, либо с помощью ctrl-a d, за которым следует соответствующий sudo kill -9 <ID>. Впоследствии, похоже, нет никаких доказательств наличия экземпляра экрана (sudo lsof / dev / tty * не показывает «screen»), однако запуск моей программы c завершается неудачно. Насколько я могу судить, команда open (...) просто зависает. Единственный способ восстановить подключение - это извлечь и снова вставить USB-кабель в устройство.

Итак,

  • 1) Есть ли лучший способ закрыть экземпляр «экрана», чем два, которые я использовал?
  • 2) Почему бы "открыть" не вернуть?

1 Ответ

0 голосов
/ 25 апреля 2020

1) Есть ли лучший способ закрыть экземпляр "экрана", чем тот, который я использовал?

Это не имеет значения, если ваша программа сделана независимой любой предыдущей конфигурации и выполняет свою собственную полную инициализацию.


2) Почему «open» не возвращает?

printf после open () никогда не запускается, когда в этом режиме порт заблокирован

Системный вызов open () для последовательного терминала может блокироваться, если не установлена ​​линия DCD (Data Carrier Detect) от модема.
Ваша программа может игнорировать состояние линии DCD во время open () , указав опцию O_NONBLOCK, например:

fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);

Однако эта опция также переведет последовательный терминал в неблокирующий режим, который заставит ваше приложение (неэффективно) опрашивать систему на предмет чтения данных вместо использования предпочтительной управляемой событиями возможности.
Ваша программа может вернуться в режим блокировки, выполнив fcntl () * 10 24 * вызов для очистки опции неблокирования, например:

fcntl(fd, F_SETFL, 0);  

Выше фактически очищаются пять изменяемых флагов состояния файла, то есть O_APPEND, O_ASYN C, O_DIRECT, O_NOATIME и O_NONBLOCK.


Код ядра Linux, который блокирует open () последовательного терминала от продолжения, является while (1) l oop в tty_port_block_til_ready () .
Обратите внимание, что если при предыдущем открытии последовательного терминала был установлен флаг CLOCAL term ios, то не предполагается, что модем подключен, и проверка на DCD прекращена.

...