LINUX.ORG.RU

Есть ли готовые решения для чтения из одного tty одновременно двумя процессами для получения одних и тех же данных

 


1

2

Есть два процесса на одной машине которые должны слушать один и тот же последовательный порт. Цель заключается в том что они должны получить одни и те же данные. Т.е. если пришло на порт число 0xff один раз, то каждый процесс получает 0xff.

★★★

Ответ на: комментарий от Stanson

Сгодится, если ТСу не вздумается еще и писать в порт. Тогда уже без специального демона не обойтись.

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

man tee

И как это применить? У меня процессы знают только имя файла последовательного порта.

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

Ну скажи твоему процессу, что у тебя порт не /dev/ttyS0 а stdin.

Если твой процесс не умеет в stdin - то man fifo , man mkfifo. Скажи процессу, что порт у тебя /tmp/fifo_0 например.

Ещё почитай man pty. - тоже вариант.

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

pty я знаю, но это уже деталь от велосипеда, а не готовое решение.

Ну так используй tee для размножения потока, и pty в качестве файлов для tee и твоих процессов.

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

Не проканает: по ioctl'ам его процесс поймет, что подсунутое — не порт, и пошлет нахрен.

Если нельзя изменить процесс (скажем, голимая спираченная проприетарщина), то нужно будет либо использовать какое-нибудь готовое средство (ЯХЗ, может и есть подобное), либо писать свой ведромодуль, который будет заниматься размножением портов.

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

Не проканает: по ioctl'ам его процесс поймет, что подсунутое — не порт, и пошлет нахрен.

Если процесс настолько лезет в порт, то надо использовать pty. ioctl будут работать.

Stanson ★★★★★
()

Вобщем эта задача решается через использование специального демона. В природе их существует два-три нормальных. Один из них используется в Linaro LAVA. Если я правильно помню то он шарит данные по TCP и имеет кучу вкусных плюшек.

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

то нужно будет либо использовать какое-нибудь готовое средство (ЯХЗ, может и есть подобное), либо писать свой ведромодуль, который будет заниматься размножением портов.

Можно ещё прикольнее, если у вас есть 6 сериальных порта, то подключаем проприетарщины к двум портам, но эти порты не куда надо, а null-модемнымы кабелями к ещё двум портам, пишем демон, который общается с портами 3-4 и реальными железками на 5-6 портах :))

vodz ★★★★★
()

Ладно, парни, спасибо. Вижу нет готового простого решения, ПО моё, придется переписывать.

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

Ладно, парни, спасибо. Вижу нет готового простого решения, ПО моё, придется переписывать.

Ну отчего же :)

socat /dev/ttyUSB0,raw,echo=0 - | tee >(socat - "PTY,link=/tmp/ttyV0,raw,echo=0,waitslave") | socat - "PTY,link=/tmp/ttyV1,raw,echo=0,waitslave"

cat /tmp/ttyV0
cat /tmp/ttyV1
alx777 ★★
()
Ответ на: комментарий от cvv

ser2net по-моему эта штука называется, но к ней надо цепляться по TCP и не уверен что она может один порт на несколько коннекшенов расшарить. Хотя вроде какой-то monitor mode там есть

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

Ты мыслишь в правильном направлении но конкретно ser2net шарить порт не умеет.

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

Если ioctl'ы будут тут ретранслироваться, особенно те которые устанавливают параметры порта, то работать оно врядли будет. Одно приложение устанавлиает битрейт 9600 другое 115200 а третье вообще решает что пора бы это дело все срезетить

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

Если твоя утилита работает с последовательным портом, она как минимум настроит нужные режимы, т.е. будет вызывать ioctl'ы. Без этого смысл от нее?

А чтобы cat правильно с портом работал, надо сначала каким-нибудь minicom'ом его настроить...

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

ioctl'ы срабатывают успешно, с оригинальным портом ничего не делают, его нужно конфигурировать заранее:

$ strace -eioctl picocom -b 115200 /tmp/ttyV0 
picocom v1.7

port is        : /tmp/ttyV0
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

ioctl(3, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_CONTINUE or TCSETSF, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCGETS, {B115200 -opost -isig -icanon -echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 -opost -isig -icanon -echo ...}) = 0
ioctl(0, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
alx777 ★★
()
Ответ на: комментарий от alx777

Тогда круто, это то, что нужно ТСу.

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

tee ожидает увидеть в качестве параметров имена файлов

>(socat - «PTY,link=/tmp/ttyV0,raw,echo=0,waitslave»)
создает socat процесс и соответствующий /dev/fd/<n> инпут файл который передается tee и куда копируется то что было получено на входе tee

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

Понял. А сначала не понял что тут файлы, а не каналы.

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

socat /dev/ttyUSB0,raw,echo=0 - | tee >(socat - «PTY,link=/tmp/ttyV0,raw,echo=0,waitslave») | socat - «PTY,link=/tmp/ttyV1,raw,echo=0,waitslave»

Слабо, но понял работу этой команды. Я так понимаю что связь по этой команде полудуплексная, а можно ли сконструировать из этого полный дуплекс? Например если в конце я припишу > /dev/ttyUSB0? На мой взгляд, как я понимаю, это должно перенаправить вывод на /tmp/ttyV0 и /tmp/ttyV1 на /dev/ttyUSB0 и при этом этот же вывод полезет на ввод из /tmp/ttyV1.

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

socat /dev/ttyUSB0,raw,echo=0 - | tee >(socat - «PTY,link=/tmp/ttyV0,raw,echo=0,waitslave») | socat - «PTY,link=/tmp/ttyV1,raw,echo=0,waitslave»

Ох, нет, errno ESPIPE при open().

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

а можно ли сконструировать из этого полный дуплекс?

Думаю это будет сложно сделать

Если реально надо шарить этот порт в обе стороны между несколькими процессами то лучше написать своего демона который будет создавать нужное количество pty и разбираться кому, что и в какой последовательности туда можно писать. Иначе трудно предсказать что будет записано в порт если два процесса будут делать это одновременно

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

Ой, нет, я что-то неправильно сделал, всё работает. Только процессы отвечать не могут. Буду думать как из этого соорудить дуплекс.

За наводку на strace отдельное спасибо, я не знал о существовании такого.

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

У меня получилось:

socat /dev/ttyUSB0,raw,echo=0,b19200 - | tee >(socat - PTY,link=/dev/ttyV0,raw,echo=0,waitslave > /dev/ttyUSB0) | socat - PTY,link=/dev/ttyV1,raw,echo=0,waitslave > /dev/ttyUSB0

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

Не, они пишут только по запросу от ведущего устройства которое через этот порт им по очереди запросы присылает.

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