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

    From Denis Sovkov@2:5020/570.77 to All on Wed Nov 29 22:02:08 2023

    Hello everybody!


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


    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Sergei Podstrigailo@2:5000/28 to Denis Sovkov on Thu Nov 30 10:03:22 2023
    Hello Denis!

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

    Hello everybody!


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


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

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


    Sergei

    --- GoldED/W32 3.0.1
    * Origin: ua9ov[at]dxsoft.com http://www.dxsoft.com (2:5000/28)
  • From Eugene Grosbein@2:5006/1 to Denis Sovkov on Thu Nov 30 12:10:31 2023
    29 нояб. 2023, среда, в 22:02 NOVT, Denis Sovkov написал(а):

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

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

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

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

    Eugene
    --- slrn/1.0.3 (FreeBSD)
    * Origin: RDTC JSC (2:5006/1@fidonet)
  • From Denis Sovkov@2:5020/570.77 to Sergei Podstrigailo on Thu Nov 30 14:41:38 2023

    Hello Sergei!

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

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

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

    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Denis Sovkov@2:5020/570.77 to Eugene Grosbein on Thu Nov 30 14:42:18 2023

    Hello Eugene!

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

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

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

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

    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Denis Sovkov@2:5020/570.77 to Sergei Podstrigailo on Thu Nov 30 14:50:34 2023
    * Replying to a msg in CARBONZ (My personal EchoMail)


    Hello Sergei!

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

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

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

    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Denis Sovkov@2:5020/570.77 to Denis Sovkov on Thu Nov 30 17:37:20 2023

    Hello Denis!

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


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

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

    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Eugene Grosbein@2:5006/1 to Denis Sovkov on Sat Dec 2 13:51:01 2023
    30 нояб. 2023, четверг, в 14:42 NOVT, Denis Sovkov написал(а):

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

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

    Eugene
    --- slrn/1.0.3 (FreeBSD)
    * Origin: RDTC JSC (2:5006/1@fidonet)
  • From Eugene Grosbein@2:5006/1 to All on Sat Dec 2 13:51:50 2023
    02 дек. 2023, суббота, в 13:51 NOVT, Eugene Grosbein написал(а):

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

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

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

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

    Eugene
    --
    Поэты - страшные люди. У них все святое.
    --- slrn/1.0.3 (FreeBSD)
    * Origin: RDTC JSC (2:5006/1@fidonet)
  • From Denis Sovkov@2:5020/570.77 to Eugene Grosbein on Sat Dec 2 16:09:52 2023
    * Replying to a msg in CARBONZ (My personal EchoMail)


    Hello Eugene!

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

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

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

    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: ----> Default GoldED Origin <---- (2:5020/570.77)
  • From Sergei Podstrigailo@2:5000/28 to Denis Sovkov on Sun Dec 3 05:54:54 2023
    Hello Denis!

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


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

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


    === 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

    --- GoldED/W32 3.0.1
    * Origin: ua9ov[at]dxsoft.com http://www.dxsoft.com (2:5000/28)
  • From Denis Sovkov@2:5020/570.77 to Sergei Podstrigailo on Mon Dec 4 19:37:00 2023
    * Replying to a msg in CARBONZ (My personal EchoMail)


    Hello Sergei!

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

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

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

    Denis


    --- GoldED+/LNX 1.1.5-b20180707
    * Origin: --=<(R2AIV station)>=-- (2:5020/570.77)