LINUX.ORG.RU

Работа с com-port. Странная буферизация


0

0

Доброго времени суток. Уж не знаю, к кому обратиться. Решил к вам.

Есть задача. Некий девайс шлёт по com-порту какие-то команды на комп. Необходимо вклинится в этот процесс передачи и логировать все команды. То есть ком-кабель разветвляется, подсединяется ко второму компу, на котором стоит linux и там ведётся лог.

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

Собственно, идея такая. Ждём пока придёт байт. Ждём следующий. Если следующий пришёл за время, превышающее некоторое пороговое значение, то это новая команда - выводим в лог старую команду, новый байт заносим в буфер. Если нет - добавляем этот байт в наш буфер.

В теории довольно просто. На практике - не очень

Приходящие команды длиной больше 8 байт разбиваются на части по 8 байт. Разница по времени между этими командами по таймеру составляет около 4 милисекунд. Однако, это совсем не соответствует действительности - по осциллографу видно, что команда передаётся целиком, время передачи одного байта порядка 200 мкс.

Пытался время засекать и через select, и через gettimeofday. Делал read с засечением времени, и ioctl(fd, FIONREAD, &bytes) чтобы смотерть, сколько данных в буфере. Одно и то же - всегда эти 8 байт вылезают.

Может, проблема в какой-нибудь странной буферизации в драйвере ком-порта?

Собственно, что делать? Куда копать? В инете все мануалы по работе с ком-портом написаны в терминах read\write. Может, надо попытаться залезть на уровень пониже?

ЗЫЖ Была бы возможность - можно было бы это сделать всё на микроконтроллере, но сказали надо на linux.

ЗЗЫЖ Сейчас всё тестирую на OSADL LiveCD. Это Knoppix с 2.6.23.1 vanilla kernel. Если найду решение, буду ставить rt ядро в дебиан.

Заранее спасибо за ответы

Собственно, идея такая. Ждём пока придёт байт. Ждём следующий. Если следующий пришёл за время, превышающее некоторое пороговое значение, то это новая команда - выводим в лог старую команду, новый байт заносим в буфер. Если нет - добавляем этот байт в наш буфер.

Для произвольно взятого протокола - неверная концепция.

pathfinder ★★★★ ()

man termios

Обрати внимание на VMIN, VTIME.

pathfinder ★★★★ ()

Вообще-то команды отделяются не временным интервалом, а протоколом. Если по протоколу отделять возможности нет, то надо следить за состоянием сом-порта (т.е. работать с драйвером), т.е следить за RTS/CTS/DSR/DTR в аппаратном управлении или за байтами Xon/Xoff в потоке данных в софтовом управлении. Между высокоуровневыми командами драйвер порта менят состояние порта, здесь и лежат границы между командами (обычно).

ЗЫ. Как это делать под линукс не скажу, не пробовал, а под винду делал.

cathode ()

> Может, проблема в какой-нибудь странной буферизации в драйвере ком-порта?

Почему «странной»? 16550A стандартно дергает прерывание на 8 байтах в буфере. В теории можно поднять до 14 (или опустить до 4 или 1).

В теории довольно просто.


Это потому что теория идиотская. Либо ты ловишь на аппартном уровне - тогда снимай осциллографом сигнал, либо на программном - тогда хвост с кабелем и прочий linux тебе нафик не нужен.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

>Почему «странной»? 16550A стандартно дергает прерывание на 8 байтах в буфере. В теории можно поднять до 14 (или опустить до 4 или 1).

Был бы рад, если бы вы подсказали, каким образом опустить до 1.

Обрати внимание на VMIN, VTIME.

VTIME задаёт время в милисекундах =\

Для произвольно взятого протокола - неверная концепция.

Можно поподробнее почему?

Narsil ()
Ответ на: комментарий от Narsil

>Можно поподробнее почему?

Вообще-то команды отделяются не временным интервалом, а протоколом.

Уже вроде сказали.

pathfinder ★★★★ ()
Ответ на: комментарий от LamerOk

>Почему «странной»? 16550A стандартно дергает прерывание на 8 байтах в буфере. В теории можно поднять до 14 (или опустить до 4 или 1).

Спасибо за наводку. Указал размер FIFO буффера равный 1 и всё запахало как часы.

Narsil ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.