URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9206
[ Назад ]

Исходное сообщение
"Работа с com-портом в Linux"

Отправлено newbie , 01-Авг-11 17:40 
Здравствуйте!

Возникла необходимость научиться работать с com-портом под Linux.

Мой прошлый опыт в этом направлении, к сожалению, относится к далеким временам лет 15-20 назад. Разработки были под голый DOS и все было проще пареной репы: расчеты/логика на ЯВУ, работа с портами/памятью - inline вставки на ассемблере или отдельно собираемые .obj на том же ассемблере. Продукты с "доведенной" логикой прогоняли под профайлером и пару-тройку самых медленных функций тоже переписывали на ассемблере.

Интернет пестрит статьями по теме, но основная масса, насколько я понимаю, описывает процесс со стороны embedded\ARM и т.п., что мне не очень близко.

Хотелось бы советов от почтеннейшей публики - с чего мне проще начать со своим "багажом", чего остерегаться, на что обратить внимание.

В частности интересны такие вопросы:
1. Если нет особо жестких требований по времени - достаточно ли просто работы с /dev/ttySX, в частности непонятно - можно ли контролировать последовательность приема-передачи (мне важно знать, что такой-то байт был получен до или после отправки такой-то команды)?
2. Правильно ли я понимаю, что вместо того, чтобы расставлять вычисления маленькими кусочками между чтением/записью, сейчас более правильно просто "отсаживать" обмен в отдельный поток с более высоким приоритетом?
3. Важна ли сейчас разница между аппаратными реализациями? Или если ядро распознало устройство и создало в /dev ссылку, то дальнейшие различия несущественны?
4. Значительны ли отличия в работе "классических" портов и преобразователей COM-USB (возможность последних пропадать\появляться мне не важна, важны именно отличия в программировании)?
5. Что можно предпринять во избежание затрат на другие процессы? Пассивная защита (поменьше активных демонов) понятна, а активная?

Детали, если они имеют значение: архитектура - i386, скорости мизерные, единицы-десятки байт в секунду, родной софт работает на 2400, 7/1. Оборудование - немецкие промышленные весы времен царя гороха, но прекрасно работающие до сих пор, в отличие от фирмы-продавца.

Надеюсь на ваши советы, заранее благодарен!


Содержание

Сообщения в этом обсуждении
"Работа с com-портом в Linux"
Отправлено f00l , 02-Авг-11 14:47 
Читаешь, записываешь в файл /dev/ttySx, настраиваешь работу с устройством через функцию ioctl.

"Работа с com-портом в Linux"
Отправлено XAnder , 02-Авг-11 18:46 
На мой неискушённый взгляд вот здесь достаточно хорошо изложено:

https://www.opennet.ru/docs/RUS/serial_guide/

На хитрые вопросы отвечать не берусь.


"Работа с com-портом в Linux"
Отправлено newbie , 02-Авг-11 21:05 
Спасибо! Копию текста в другом месте видел, но дата напугала, ушел искать поновее. Оказалось - все вполне неплохо.

"Работа с com-портом в Linux"
Отправлено ACCA , 03-Авг-11 01:04 
> 1. Если нет особо жестких требований по времени - достаточно ли просто
> работы с /dev/ttySX, в частности непонятно - можно ли контролировать последовательность
> приема-передачи (мне важно знать, что такой-то байт был получен до или
> после отправки такой-то команды)?

Точная привязка по времени невозможена даже из-за буфера в 16550. В обычном Unix время между приходом байта в порт и чтением из /dev/ttySx никак не регламентировано. Посмотри внимательнее на протокол - если нельзя сделать дисциплину запрос-ответ, то может понадобится какая-нибудь RTOS.


> 2. Правильно ли я понимаю, что вместо того, чтобы расставлять вычисления маленькими
> кусочками между чтением/записью, сейчас более правильно просто "отсаживать" обмен в
> отдельный поток с более высоким приоритетом?

Сильно проще - while (select(...)) { read .... write .... }, однако см. #1. Кроме того, read может вернуть только часть посылки и нужно будет дочитывать остальное. Ещё советуют делать tcdrain перед каждой записью.


> 3. Важна ли сейчас разница между аппаратными реализациями? Или если ядро распознало
> устройство и создало в /dev ссылку, то дальнейшие различия несущественны?

Именно так.


> 4. Значительны ли отличия в работе "классических" портов и преобразователей COM-USB
> (возможность последних пропадать\появляться мне не важна, важны именно отличия в
> программировании)?

ioctl на уровне /dev/ttyU* и /dev/ttyS* не различаются.


> 5. Что можно предпринять во избежание затрат на другие процессы? Пассивная защита
> (поменьше активных демонов) понятна, а активная?

На таких скоростях достаточно, чтобы не было свопа. Остальное - мелочи, на которые можно не обращать внимания. Хочется поиграть в нагруженную систему - можно сделать SCHED_FIFO через sched_setscheduler.


"Работа с com-портом в Linux"
Отправлено newbie , 03-Авг-11 22:09 
>> 1. Если нет особо жестких требований по времени - достаточно ли просто
>> работы с /dev/ttySX, в частности непонятно - можно ли контролировать последовательность
>> приема-передачи (мне важно знать, что такой-то байт был получен до или
>> после отправки такой-то команды)?
> Точная привязка по времени невозможена даже из-за буфера в 16550. В обычном
> Unix время между приходом байта в порт и чтением из /dev/ttySx
> никак не регламентировано. Посмотри внимательнее на протокол - если нельзя сделать
> дисциплину запрос-ответ, то может понадобится какая-нибудь RTOS.

Я выразился невнятно. Точная привязка ко времени - не нужна, нужно знать что такой-то ответ пришел после такой-то команды, т.е. порядок ответов относительно команд, а не относительно времени. Железка отвечает за известное время и всегда шестью байтами, если не все нужны, лишние - пустые, первый всегда маркер ответа (не может встречаться в данных). По своей инициативе ничего не присылает, но если долго (около 40 секунд) нет команд, сигналит разрыв.

Родная софтина даже не пытается время измерять (таймер не перехватывает и не программирует), а просто после каждой команды гоняет холостой цикл, и только после этого читает. В связи с этим найти для нее подходящий комп стало хорошим квестом. Из под вайна она работает скверно.

До RTOS, надеюсь, дело не дойдет.

>> 2. Правильно ли я понимаю, что вместо того, чтобы расставлять вычисления маленькими
>> кусочками между чтением/записью, сейчас более правильно просто "отсаживать" обмен в
>> отдельный поток с более высоким приоритетом?
> Сильно проще - while (select(...)) { read .... write .... }, однако
> см. #1. Кроме того, read может вернуть только часть посылки и
> нужно будет дочитывать остальное. Ещё советуют делать tcdrain перед каждой записью.

Спасибо, tcdrain и tcflush, похоже - то, что мне нужно. Часть посылки - не страшно, маркерный байт есть, да и перезапросить можно.

>> 3. Важна ли сейчас разница между аппаратными реализациями? Или если ядро распознало
>> устройство и создало в /dev ссылку, то дальнейшие различия несущественны?
> Именно так.
>> 4. Значительны ли отличия в работе "классических" портов и преобразователей COM-USB
>> (возможность последних пропадать\появляться мне не важна, важны именно отличия в
>> программировании)?
> ioctl на уровне /dev/ttyU* и /dev/ttyS* не различаются.

Ясно. Я опасался, что нужно при этом следить еще за каким-либо материнским устройством.

>> 5. Что можно предпринять во избежание затрат на другие процессы? Пассивная защита
>> (поменьше активных демонов) понятна, а активная?
> На таких скоростях достаточно, чтобы не было свопа. Остальное - мелочи, на
> которые можно не обращать внимания. Хочется поиграть в нагруженную систему -
> можно сделать SCHED_FIFO через sched_setscheduler.

Ясно.

Большое спасибо за ответы!