Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Доступ к последовательным устройствам

Как все устройства в Unix-системах, последовательные порты доступны через файлы устройств в каталоге /dev. Есть два множества файлов устройств, связанных с последовательными драйверами, и для каждого порта имеется по одному файлу каждого множества. В зависимости от файла, к которому обращаются, устройство будет вести себя по-разному.

Файлы из первого множества требуются в случае, если порт используется для приема. Они имеет старший номер 4 и имена ttyS0, ttyS1, ttySn. Второе множество используется для передачи, файлы названы cua0, cua1, cuan и имеют старший номер 5. Младшие номера одинаковы для обоих типов. Если модем подключен к одному из портов от COM1 до COM4, младший номер будет номером COM-порта плюс 63. Если Ваша настройка отлична от этой, например, при использовании платы, поддерживающей множество последовательных линий, пожалуйста, обратитесь к Serial Howto. Таким образом, порт COM1: обозначен как /dev/ttyS0, COM2: как /dev/ttyS1 и так далее.

Файлы серии cua, или "callout", были созданы, чтобы решить проблему ухода от конфликтов на последовательных устройствах для модемов, которые должны поддерживать входящие и исходящие подключения. К сожалению, они создали только лишние проблемы и теперь, вероятно, выйдут из употребления. Давайте кратко рассмотрим проблему.

Linux, как и Unix, позволяет открыть устройство или любой файл более, чем одному процессу одновременно. К сожалению, это редко работает хорошо с tty-устройствами, поскольку два процесса будут почти наверняка сталкиваться друг с другом. К счастью, был изобретен механизм, позволяющий процессу проверять, было ли tty-устройство уже открыто другим процессом. Механизм использует файлы блокировки (lock files). Идея состояла в том, что, когда процесс открывает tty-устройство, он проверит существование файла в специальном месте, с именем, соответствующим устройству, которое процесс хочет открыть. Если файл не существует, процесс создает его и открывает tty-устройство. Если файл существует, процесс считает, что другой процесс уже открыл это tty-устройство, и выполняет соответствующее этой ситуации действие. Для построния системы управления файлами блокировки использован простой прием: создавший файл блокировки процесс должен записать свой process ID (pid) в него.

Механизм файлов блокировки работает хорошо, если все файлы пишутся в определенное место, и все программы знают, где их искать и создавать. Но в Linux единого мнения по данному вопросу не было до появления Linux Filesystem Standard, который определил стандартное расположение для файлов блокировки. Раньше эти файлы хранились минимум в четырех каталогах: /usr/spool/locks, /var/spool/locks, /var/lock и /usr/lock. Беспорядок вызвал хаос. Программы открывали файлы блокировки в различных каталогах и при этом пытались управлять одними и теми же устройствами. Получалось, будто файлы блокировки не использовались вообще.

Устройства cua были созданы, чтобы обеспечить решение этой проблемы. Вместо использования файлов блокировки, чтобы предотвратить столкновения между программами, желающими использовать последовательные устройства было решено, что ядро может обеспечивать простые средства для решения того, кто должен иметь доступ. Если устройство ttyS было уже открыто, попытка открыть cua кончится ошибкой, которую программа могла бы интерпретировать соответствующим образом. Если устройство cua было уже открыто, и была сделана попытка открыть ttyS, запрос будет заблокирован, то есть, он будет ждать, пока cua не будет закрыто другим процессом. Это работало хорошо, если Вы имели один модем, который сконфигурировали для дозвона к провайлеру и приема входящих звонков. Но это не работало в средах, где есть много программ, желающих работать на том же самом устройстве. Единственный способ решить проблему состоял в том, чтобы использовать файлы блокировки! С чего начали, к тому и вернулись...

Решение принес стандарт файловой системы Linux Filesystem Standard. Теперь файлы блокировки хранятся в /var/lock, а имя файла для блокировки устройства ttyS1 выглядит как LCK..ttyS1. Файлы блокировки cua должны также войти в этот каталог, но использование устройств cua теперь явно излишне.

Устройства cua какое-то время еще будут поддерживаться по соображениям совместимости, но едва ли это продлится долго. Лучше всего использовать ttyS и следить, чтобы система была совместима с Linux FSSTND или по крайней мере, чтобы все программы, использующие последовательные устройства, договаривались о месте хранения и именах файлов блокировки. Большая часть программного обеспечения, имеющего дело с последовательными tty-устройствами, обеспечивает опцию времени компиляции, чтобы определить расположение файлов блокировки. Ищите что-то подобное LOCKDIR в файле Makefile или в файле заголовка компиляции. Если Вы компилируете программное обеспечение самостоятельно, самое лучшее изменить этот параметр, чтобы соответствовать FSSTND. Если вы используете готовые двоичные файлы и не уверены, где программа будет создавать файлы блокировки, Вы можете использовать следующую команду, чтобы получить информацию:
strings binaryfile | grep lock
Если найденное расположение не соответствует остальной части Вашей системы, Вы можете попробовать создать символическую связь из каталога блокировок, который неправильная программа хочет использовать, обратно к /var/lock. Ничего хорошего в таком подходе нет, но это будет работать.

Файлы последовательных устройств

Младшие числа идентичны для обоих типов последовательных устройств. Если модем подключен к одному из портов от COM1 до COM4, младший номер будет номером COM-порта плюс 63. Если Ваша настройка отлична от этой, например, при использовании платы, поддерживающей множество последовательных линий, пожалуйста, обратитесь к Serial Howto.

Предположим, что модем находится на COM2. Таким образом, младший номер будет 65, а старший номер для дозвона будет 4. Следовательно, должно быть устройство ttyS1, которое имеет этот номер. Просмотрите список последовательных устройств в каталоге /dev. Колонки 5 и 6 должны показать старшие и младшие номера соответственно:

$ ls -l /dev/ttyS*
0 crw-rw----   1 uucp     dialout    4,  64 Oct 13  1997 /dev/ttyS0
0 crw-rw----   1 uucp     dialout    4,  65 Jan 26 21:55 /dev/ttyS1
0 crw-rw----   1 uucp     dialout    4,  66 Oct 13  1997 /dev/ttyS2
0 crw-rw----   1 uucp     dialout    4,  67 Oct 13  1997 /dev/ttyS3

Если нет таких устройств, Вы должны создать их: войдите как пользователь root и наберите:

# mknod -m 666 /dev/ttyS1 c 4 65
# chown uucp.dialout /dev/ttyS1
Различные дистрибутивы Linux используют немного отличающиеся cтратегии в плане того, кто должен быть владельцем последовательных устройств. Иногда они будут принадлежать root, иногда другому пользователю, например, uucp в этом примере. Новые дистрибутивы имеют группу для набора номера телефона, и любой пользователь, которому разрешено это делать, должен быть просто внесен в нее.

Некоторые люди предлагают создание символической связи /dev/modem на устройство модема так, чтобы пользователи не должны были запоминать несколько не понятное ttyS1. Однако, Вы не можете использовать modem в одной программе, а реальное имя файла устройства в другой. Это потому, что программы используют так называемые файлы блокировки (lock files) для обозначения того, что устройство занято. Применение различных файлов устройства для того же самого порта приведет к тому, что программы окажутся не в состоянии распознать файлы блокировки для каждого имени и будут обращаться к устройству в одно и то же время. В результате, приложения не будут работать вообще.