LINUX.ORG.RU

при каких условиях на ком-порте в raw-режиме может возникать ситуация EOF ????


0

0

порт открывается без O_NONBLOCK но с VMIN && VTIME установленными в 0.

самое интересное что это состояние не снимается с порта при поступлении в порт новых данных

★★★★★


"ситуация EOF" - это как именно?

например по http://netbsd.gw.com/cgi-bin/man-cgi?termios+4+NetBSD-current

---cut---
Case D: VMIN = 0, VTIME = 0
The minimum of either the number of bytes requested or the number of bytes currently available is returned without waiting for more bytes to be input. If no characters are available, read returns a value of zero, having read no data.
---cut---

// wbr

klalafuda ★☆☆
()

А каким образом (при VMIN=VTIME=0) ты собственно констатируешь ситуацию EOF?

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

>"ситуация EOF" - это как именно?

это когда select() вернул что в ком-порте есть данные для чтения а следующий за ним read вернул 0 байт.

после длительного вникания man tcsetattr и аналогии с сокетами я воспринял эту ситуацию как EOF.

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

Хммм... покажи плиз твой код, который устанавливает параметры терминального девайса.
BTW, данные, приходящие на порт - ASCII или бинарные?
И попробуй все-таки, просто для эксперимента, поставить VTIME=0 и VMIN=1.

Onanim
()

Может быть это BREAK на входе? То бишь низкий длительный сигнал на входе СОМ-порта.

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

>данные, приходящие на порт - ASCII или бинарные? 

бинарные

>И попробуй все-таки, просто для эксперимента, поставить VTIME=0 и VMIN=1.

а обьясни ход своих мыслей???

>Хммм... покажи плиз твой код, который устанавливает параметры терминального девайса. 

    if (tcgetattr(port->fd, &ti) < 0)                                                                                          
       { syslog(LOG_ERR, "%s(%s):error getting terminal line modes: %m",__func__, devfile); close(port->fd);free(port); return 
NULL; }                                                                                                                        
                                                                                                                               
    cfmakeraw(&ti);                                                                                                            
    cfsetispeed(&ti, WATCHER_PORT_SPEED);                                                                                      
    cfsetospeed(&ti, WATCHER_PORT_SPEED);                                                                                      
                                                                                                                               
    //c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);                                                    
    ti.c_iflag |= IGNBRK;//???возможно имеет смысл оставить этот флаг снятым а вместо него поднять BRKINT???                   
    ti.c_iflag |= IGNPAR;//Ignore framing errors and parity errors.                                                            
    ti.c_iflag &= ~(INPCK | PARMRK);                                                                                           
    ti.c_iflag &= ~(IXOFF | IXON | IXANY);    /* disable start/stop i/o flow control*/                                         
                                                                                                                               
    //c_oflag &= ~OPOST;                                                                                                   
                                                                                                                               
    ti.c_cflag &= ~(PARENB | PARODD);  /* no parity */                                                                         
    ti.c_cflag &= ~CSTOPB;             /* 1 stop bit */                                                                        
    ti.c_cflag &= ~CRTSCTS;            /* no i/o rts/cts flow control */                                                       
    ti.c_cflag |= CLOCAL;                                                                                                      
    ti.c_cflag |= HUPCL;                                                                                                       
    ti.c_cflag |= CREAD;                                                                                                       
                                                                                                                               
    //c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);                                                                        
    //Disable  flushing  the  input and output queues when generating the SIGINT, SIGQUIT and SIGSUSP signals.             
    //ti.c_lflag &= ~(NOFLSH);//???возможно потребуется установить/снять???                                                
                                                                                                                               
    ti.c_cc[VMIN] = 0;                                                                                                         
    ti.c_cc[VTIME] = 0;                                                                                                        
                                                                                                                               
    if (tcsetattr(port->fd, TCSANOW, &ti) < 0)                                                                                 
       { syslog(LOG_ERR,"%s(%s):error setting terminal line modes: %m", __func__,  devfile); close(port->fd);free(port); return
 NULL; }

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

>Может быть это BREAK на входе? То бишь низкий длительный сигнал на входе СОМ-порта.

может. только я поднимаю флаг IGNBRK

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

если точнее то есть предположение что эта ситуация провоцируется наводками или помехами.

По крайней мере исскуственно созданные помехи провоцируют именно эту ситуацию.

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

2 cvv :

Ох блин... не знаю, что тебе сказать :-(
AFAIK, для raw serial line никакого EOF быть вообще не может
и read() не может вернуть 0 (если VMIN>0, VTIME=0). Для такой
линии ситуция, похожая на EOF - это hangup, но и она сигнализируется
как SIGHUP, а не как read()==0.
Из своего опыта я такой ситуации, как у тебя, не помню. Правда было
это не на Linux, а на SCO OpenServer и UnixWare.

Я припоминая дискуссию в где-то в comp.??? по поводу похожей проблемы
(read()==0 хотя никак не должен был). В результате у оказалось, что
у перца из-за логической ошибки вызывался read(fd, buf, n), где n
равнялось нулю. Соотвественно он и получал 0 от read(). Проверь свой
код на такую ситуацию (если у тебя n не константа), мало ли чего.

Насчет VMIN=1 вместо VMIN=0. Не могу это объяснить. Просто попробуй.
Раз уж ты используешь select() перед чтением то никакой другой
модификации не потребуется, read() не должен блокироваться все равно.

Ну и наконец, чтобы внести ясность, возьми какой-то простенький пример
(miniterm.c) и почитай с порта им (можешь туды select() добавить, там
всего-то на пару экранов текста). Если он будет читать нормально - то
значит косяк у тебя в программе. (BTW, в miniterm.c VMIN=1).

Pls сообщай о результатах!

HTH

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

>Для такой линии ситуция, похожая на EOF - это hangup, но и она сигнализируется как SIGHUP, а не как read()==0.

расскажите по подробней о этой ситуации ато мне даже не приходилось встречать нормальное описание ситуации break и hangup несмотря на то что я немало перечитал

самая большая проблема в том что мне не удаётся вывести ком-порт из этого состояния в нормальный режим

>Из своего опыта я такой ситуации, как у тебя, не помню. Правда было это не на Linux, а на SCO OpenServer и UnixWare.

у меня эта ситуация проявляется третий раз на трёх разных железка с разными ОС включая SCO. Раньше мы её как-то бороли не прибегая к правке сырцов. Собственно причину возникновения такой ситуации я не помню.

>Я припоминая дискуссию в где-то в comp.??? по поводу похожей проблемы (read()==0 хотя никак не должен был). В результате у оказалось, что у перца из-за логической ошибки вызывался read(fd, buf, n), где n равнялось нулю. Соотвественно он и получал 0 от read(). Проверь свой код на такую ситуацию (если у тебя n не константа), мало ли чего.

на 100% не уверен но на 99.9% n>>0

>Насчет VMIN=1 вместо VMIN=0. Не могу это объяснить. Просто попробуй. Раз уж ты используешь select() перед чтением то никакой другой модификации не потребуется, read() не должен блокироваться все равно.

попробую. мож что прояснится

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

да я как-то слыхал, что читают спецкурсы даже по поверке качества линий связи (пусть даже это и компорт), раньше нифига не понимал и наежжал на этих людей, а потом уже вогнал, что всетки это важно. допустим шлешь 10 пакетов а доходит 8, значит линия некачественная...

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

>допустим шлешь 10 пакетов а доходит 8, значит линия некачественная...

эт мы понимаем.

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

и как понять в каком собственно состоянии находится система дабы с этим можно было как-то боротся

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

а ситуация hangup может возникнуть на сом порте при выключеном и hardware и software flow control и линии dtr замкнутой на dcd?????

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

> расскажите по подробней о этой ситуации ато мне даже не приходилось
> встречать нормальное описание ситуации break и hangup
>

Цитируя Стивенса APUE:
SIGHUP - This signal is sent to the controlling process (session leader) associated with a controlling terminal if a disconnect is
detected by the terminal interface. This signal is generated for
this condition only if the terminal's CLOCAL flag is not set.

Очевидно это к тебе не относится - во-первых ты вроде
ставишь CLOCAL, а в-вторых ты наверное открываешь девайс с
флагом O_NOCTTY (так ведь?).

Про break, оттуда-же:
If BRKINT is set and IGNBRK is not set, when a BREAK is received the
input and the output queues are flushed and a SIGINT is generated.
...
If neither BRKINT not IGNBRK is set, then a BREAK is read as a single
characted '\0', unless PARMRK is set, in which case the BREAK is
read as the three byte sequence \377 \0 \0

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

>> расскажите по подробней о этой ситуации ато мне даже не приходилось встречать нормальное описание ситуации break и hangup

>Цитируя Стивенса APUE:

>SIGHUP - This signal is sent to the controlling process (session leader) associated with a controlling terminal if a disconnect is detected by the terminal interface. This signal is generated for this condition only if the terminal's CLOCAL flag is not set.

>Очевидно это к тебе не относится - во-первых ты вроде ставишь CLOCAL, а в-вторых ты наверное открываешь девайс с флагом O_NOCTTY (так ведь?).

да, ставлю clocal, как показано во фрагменте кода, и открываю с флагом O_NOCTTY.

вобщем на очереди эксперимент с vmin=1

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

>вобщем на очереди эксперимент с vmin=1

эксперимент поставлен. результат - тоже

приведение системы в чувство выполнил при помощи установки скорости в B0 и последующим переоткрытием порта

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

> приведение системы в чувство выполнил при помощи установки
> скорости в B0 и последующим переоткрытием порта
>

В смысле - один раз переоткрыл порт, и после этого все стало OK?

BTW я попробовал у себя, соединив два порта кабелем, писать/читать
с использование select(). Работает как часы - если select() обещал,
то read() получается.
Наверное, что-то специфическое, связанное с твоими железками происходит.

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

>> приведение системы в чувство выполнил при помощи установки скорости в B0 и последующим переоткрытием порта

>В смысле - один раз переоткрыл порт, и после этого все стало OK?

Нет. приблизительно раз 10.

>BTW я попробовал у себя, соединив два порта кабелем, писать/читать с использование select(). Работает как часы - если select() обещал, то read() получается.

у меня тоже работает, но при ДЛИТЕЛЬНОЙ эксплуатации при отсутсвии исскуственных помех приблизительно раз в неделю имеем такой трабл. до сего времени лечили только перезагрузкой но проэктируемая система не допускает случайных перезагрузок. следственно ищем пути решения проблемы без рестарта.

>Наверное, что-то специфическое, связанное с твоими железками происходит.

возможно. Сейчас думаем можно ли это спровоцировать под виндузой и как она себя поведёт дабы быть уверенным что крайнее железо а не линукс.

кстати мать - четырёхпортовая via epia-cl

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

исследование воздействия внешней исскуственной помехи дало следующие результаты: "глюки" начинаются секунд через 30 после начала воздействия помехи и заканчиваются сразу после её окончания.

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

Ты чего, издеваешься? Какая может быть помеха на СОМ-порту?

У тебя что, километровый провод? Если у тебя длина кабеля более 15-30 метров, то решение должно быть другое. И скорость обратно пропорциональна длине. Для 10-метрового кабеля не более 64-56 кбит/сек.

Или может быть земляного провода нет в кабеле? Или в кабеле висячие провода? В длинном (более 2 м), скоростном (более 19 кбит) кабеле каждая сигнальная жилка должна быть свита с земляной (если ленточный кабель используется, то земляные и сигнальные должны чередоваться). Если в кабеле есть свободные жилки, то все они должны сидеть на земле с обоих концов. Не должно быть жилок, с одной стороны кабеля свободных, а с другой сидящих на земле или сигнальном контакте (тк это антенны). Если у тебя с одной стороны какое-то левое устройство, то оно может использовать не все сигнальные контакты, получится та самая антенна.

Все устройства должны быть заземлены в одну точку, и не в розетку, а об контур заземления. На крайняк друг об друга.

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

> "глюки" начинаются секунд через 30 после начала воздействия помехи и заканчиваются сразу после её окончания.

По всему видать, на вход начинают переть испорченные посылки, как то: с неправильной длиной, четностью и все такое. Это приемопередатчик и воспринимает, как break.

Проверить можешь просто подав постоянное напряжение на вход СОМ-порта. Положительное, если не ошибаюсь, от 3 до 12 вольт.

Ну и осциллограф, тебе в руки.

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

хм. спасибо!

но ведь у меня стоит ignbrk. почему тогда последствия break видны из юзерспейса

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