Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Непонятки с read и write

3 views
Skip to first unread message

Denis Sovkov

unread,
Nov 29, 2023, 2:15:02 PM11/29/23
to

Hello everybody!


Ситауция следующая: имеем программу, программа открывает /dev/ttyUSB0 с флагом
O_RDWR - можно как записывать, так и читать. В программе два параллельных
потока - один раз в 3 секунды записывать текстовыю строку в открытый
дескриптор, другой считывает оттуда присланную строку ПОБАЙТНО внешним
устройством тогда, когда сможет и выводит на экран. Проблема в том, что во
входные данные попадает часть того, что пишется в дескриптор, причем независимо
от времени. Пробовал защищать дескриптор мютексом - не помогло, мусорные данные
все равно попадают на вход (кстати, нужные данные при этом тоже считываются).
Пробовал ставить флаг O_DSYNC - тоже не помогло. Мозможно, нужно очищать буфер
(какой и как?) сразу после отправки строки. В потоках буферы используются
разные - для каждого потока свой. Имею ввиду очистку выходного буфера, который
пишет write. ЧЯДНТ? Куда копать?


Denis


Sergei Podstrigailo

unread,
Nov 29, 2023, 10:15:02 PM11/29/23
to
Hello Denis!

29 Nov 23 22:02, Denis Sovkov wrote to All:

DS> Hello everybody!


DS> Ситауция следующая: имеем программу, программа открывает /dev/ttyUSB0
DS> с флагом O_RDWR - можно как записывать, так и читать. В программе два
DS> параллельных потока - один раз в 3 секунды записывать текстовыю строку
DS> в открытый дескриптор, другой считывает оттуда присланную строку
DS> ПОБАЙТО внешним устройством тогда, когда сможет и выводит на экран.
DS> Проблема в том, что во входные данные попадает часть того, что пишется
DS> в дескриптор, причем независимо от времени. Пробовал защищать
DS> дескриптор мютексом - не помогло, мусорные данные все равно попадают
DS> на вход (кстати, нужные данные при этом тоже считываются). Пробовал
DS> ставить флаг O_DSYNC - тоже не помогло. Мозможно, нужно очищать буфер
DS> (какой и как?) сразу после отправки строки. В потоках буферы
DS> используются разные - для каждого потока свой. Имею ввиду очистку
DS> выходного буфера, который пишет write. ЧЯДТ? Куда копать?


Лично я открываю так, и у меня всё работает как ожидается:

InputFd=open(SerDevice, O_RDWR | O_NOCTTY | O_SYNC );


Sergei

Eugene Grosbein

unread,
Nov 30, 2023, 3:15:02 AM11/30/23
to
29 нояб. 2023, среда, в 22:02 NOVT, Denis Sovkov написал(а):

DS> Ситауция следующая: имеем программу, программа открывает /dev/ttyUSB0 с
DS> флагом
DS> O_RDWR - можно как записывать, так и читать. В программе два параллельных
DS> потока
DS> - один раз в 3 секунды записывать текстовыю строку в открытый дескриптор,
DS> другой
DS> считывает оттуда присланную строку ПОБАЙТHО внешним устройством тогда,
DS> когда
DS> сможет и выводит на экран. Проблема в том, что во входные данные попадает
DS> часть
DS> того, что пишется в дескриптор, причем независимо от времени. Пробовал
DS> защищать
DS> дескриптор мютексом - не помогло, мусорные данные все равно попадают на
DS> вход
DS> (кстати, нужные данные при этом тоже считываются). Пробовал ставить флаг
DS> O_DSYNC
DS> - тоже не помогло. Мозможно, нужно очищать буфер (какой и как?) сразу
DS> после
DS> отправки строки. В потоках буферы используются разные - для каждого потока
DS> свой.
DS> Имею ввиду очистку выходного буфера, который пишет write. ЧЯДHТ? Куда
DS> копать?

Похоже на то, что у устройства, подключенного через USB,
включено эхо ввода. И ему надо его выключить.

У старых аналоговых модемов такое было и у других устройств
с terminal line discipline тоже.

Что за устройство?

Eugene

Denis Sovkov

unread,
Nov 30, 2023, 6:50:01 AM11/30/23
to

Hello Sergei!

30 Nov 23 10:03, you wrote to me:

DS>> буферы используются разные - для каждого потока свой. Имею ввиду
DS>> очистку выходного буфера, который пишет write. ЧЯДТ? Куда копать?
SP> Лично я открываю так, и у меня всё работает как ожидается:
SP> InputFd=open(SerDevice, O_RDWR | O_NOCTTY | O_SYNC );

Спасибо! Про O_NOCTTY не дочитал видимо, попробую!

Denis


Denis Sovkov

unread,
Nov 30, 2023, 6:50:02 AM11/30/23
to

Hello Eugene!

30 Nov 23 12:10, you wrote to me:

DS>> очистку выходного буфера, который пишет write. ЧЯДHТ? Куда
DS>> копать?
EG> Похоже на то, что у устройства, подключенного через USB,
EG> включено эхо ввода. И ему надо его выключить.
EG> У старых аналоговых модемов такое было и у других устройств
EG> с terminal line discipline тоже.

EG> Что за устройство?

Пролифик PL2303 (( других у нас на работе нет, увы. НО(!) пробовал с CP2102 и
FT232R - тоже самое.

Denis


Denis Sovkov

unread,
Nov 30, 2023, 7:05:01 AM11/30/23
to
* Replying to a msg in CARBONZ (My personal EchoMail)


Hello Sergei!

30 Nov 23 10:03, you wrote to me:

SP> * Origin: ua9ov[at]dxsoft.com http://www.dxsoft.com (2:5000/28)

О как! не сразу обнаружил! de R2AIV 73!

Denis Sovkov

unread,
Nov 30, 2023, 9:55:01 AM11/30/23
to

Hello Denis!

30 Nov 23 14:41, I wrote to Sergei Podstrigailo:


DS>>> буферы используются разные - для каждого потока свой. Имею ввиду
DS>>> очистку выходного буфера, который пишет write. ЧЯДТ? Куда
DS>>> копать?
SP>> Лично я открываю так, и у меня всё работает как ожидается:
SP>> InputFd=open(SerDevice, O_RDWR | O_NOCTTY | O_SYNC );
DS> Спасибо! Про O_NOCTTY не дочитал видимо, попробую!

Вобщем, добавил в open O_NOCTTY и в stty добавить -echo при настройке порта и
все поехало! Спасибо! Буду дальше ковыряться...

Denis


Eugene Grosbein

unread,
Dec 2, 2023, 7:40:02 AM12/2/23
to
30 нояб. 2023, четверг, в 14:42 NOVT, Denis Sovkov написал(а):

DS>>> очистку выходного буфера, который пишет write. ЧЯДHТ? Куда
DS>>> копать?
EG>> Похоже на то, что у устройства, подключенного через USB,
EG>> включено эхо ввода. И ему надо его выключить.
EG>> У старых аналоговых модемов такое было и у других устройств
EG>> с terminal line discipline тоже.
EG>> Что за устройство?
DS> Пролифик PL2303 (( других у нас на работе нет, увы. HО(!) пробовал с
DS> CP2102 и
DS> FT232R - тоже самое.

Так это всё переходники для USB/COM, с этого надо было начинать.
Для COM-портов существует куча настроен драйвер терминала
с вышеупомянутой serial line discipline и первым делом
надо читать man stty и выставлять драйверу верные настройки линии
через stty. Вторым делом смотреть устройство, подключенное на этой
линии, оно тоже может дублировать вывод, как это делали модемы,
если им не запретить.

Eugene

Eugene Grosbein

unread,
Dec 2, 2023, 7:40:02 AM12/2/23
to
02 дек. 2023, суббота, в 13:51 NOVT, Eugene Grosbein написал(а):

DS>>>> очистку выходного буфера, который пишет write. ЧЯДHТ? Куда
DS>>>> копать?
EG>>> Похоже на то, что у устройства, подключенного через USB,
EG>>> включено эхо ввода. И ему надо его выключить.
EG>>> У старых аналоговых модемов такое было и у других устройств
EG>>> с terminal line discipline тоже.
EG>>> Что за устройство?
DS>> Пролифик PL2303 (( других у нас на работе нет, увы. HО(!) пробовал с
DS>> CP2102 и
DS>> FT232R - тоже самое.

EG> Так это всё переходники для USB/COM, с этого надо было начинать.
EG> Для COM-портов существует куча настроен драйвер терминала

*куча настроке драйвера терминала

EG> с вышеупомянутой serial line discipline и первым делом
EG> надо читать man stty и выставлять драйверу верные настройки линии
EG> через stty. Вторым делом смотреть устройство, подключенное на этой
EG> линии, оно тоже может дублировать вывод, как это делали модемы,
EG> если им не запретить.

Eugene
--
Поэты - страшные люди. У них все святое.

Denis Sovkov

unread,
Dec 2, 2023, 8:20:02 AM12/2/23
to
* Replying to a msg in CARBONZ (My personal EchoMail)


Hello Eugene!

02 Dec 23 13:51, you wrote to me:

EG>>> У старых аналоговых модемов такое было и у других устройств
EG>>> с terminal line discipline тоже.
EG>>> Что за устройство?
DS>> Пролифик PL2303 (( других у нас на работе нет, увы. HО(!)
DS>> пробовал с CP2102 и FT232R - тоже самое.
EG> Так это всё переходники для USB/COM, с этого надо было начинать.
EG> Для COM-портов существует куча настроен драйвер терминала
EG> с вышеупомянутой serial line discipline и первым делом
EG> надо читать man stty и выставлять драйверу верные настройки линии
EG> через stty. Вторым делом смотреть устройство, подключенное на этой
EG> линии, оно тоже может дублировать вывод, как это делали модемы,
EG> если им не запретить.

Вот все как раз именно так ) Сначала скрипт запускает stty с настройками,
затем уже запускается само приложение. Запрет эхо, конечно, присутствует ))
Теперь с другой проблемой воюю - ncurses с многопоточкой не особо дружит, ну и
ладно.

Denis


Sergei Podstrigailo

unread,
Dec 2, 2023, 6:05:02 PM12/2/23
to
Hello Denis!

02 Dec 23 16:09, Denis Sovkov wrote to Eugene Grosbein:


DS> Вот все как раз именно так ) Сначала скрипт запускает stty с
DS> настройками, затем уже запускается само приложение.

А зачем такой бутерброд?
Почему в самой программе не настроить?


=== Cut ===
int OpenSerialDevice(void)
// 0 - успех
{
InputFd=open(SerDevice, O_RDWR | O_NOCTTY | O_SYNC );
if(InputFd<0) return 1;


struct termios tty;
memset (&tty, 0, sizeof(tty));
if (tcgetattr (InputFd, &tty) != 0) return 2;

cfmakeraw(&tty); // наверно, этого и достаточно, остальные флаги можно и не
// править руками...

cfsetospeed (&tty, SpeedVal);
cfsetispeed (&tty, SpeedVal);


tty.c_iflag |= IGNBRK;
tty.c_iflag &= ~IGNPAR;
tty.c_iflag &= ~PARMRK;
tty.c_iflag &= ~INLCR;
tty.c_iflag &= ~IGNCR;
tty.c_iflag &= ~ICRNL;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);

tty.c_lflag = 0;

tty.c_oflag = 0;

tty.c_cc[VMIN] = 0; // no blocking
tty.c_cc[VTIME] = 0; // read timeout


tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
tty.c_cflag |= (CLOCAL | CREAD);// do not parse control while reading
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;



if (tcsetattr (InputFd, TCSANOW, &tty) != 0) return 3;

return 0;
}
=== Cut ===


Sergei

Denis Sovkov

unread,
Dec 4, 2023, 11:55:02 AM12/4/23
to
* Replying to a msg in CARBONZ (My personal EchoMail)


Hello Sergei!

03 Dec 23 05:54, you wrote to me:

DS>> Вот все как раз именно так ) Сначала скрипт запускает stty с
DS>> настройками, затем уже запускается само приложение.
SP> А зачем такой бутерброд?
SP> Почему в самой программе не настроить?

Тестирую же-ж )) Спасибо за код! Читал про это на Хабре. Попробую!

Denis


0 new messages