Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Givoi от Август 30, 2012, 18:58



Название: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Givoi от Август 30, 2012, 18:58
Добрый вечер. Возникла такая проблема, есть программа, которая отсылает в ком порт некие данные, работа с ком портом реализована с помощью библиотеки QSerialPort 2.0

Код
C++ (Qt)
  SerialPort *serial = new SerialPort(port);
   if (serial->open(QIODevice::WriteOnly)){
       serial->setRate(SerialPort::Rate9600);
       serial->setDataBits(SerialPort::Data8);
       serial->setParity(SerialPort::NoParity);
       serial->setStopBits(SerialPort::OneStop);
       serial->setFlowControl(SerialPort::NoFlowControl);
       serial->write(message);
       serial->close();
   }
   else{
       qDebug()<<"ERROR: port "<<port<<" is close";
   }

в порт пишу :"1234567890"
На другом конце приходит только "12345" и знаки вопроса

"Другой конец" представлен в виде программы SerialMon, так же пробовал программу собственно написания, итог один..

Но это еще не все... если допустим вместо отсылающей программы запустить тот же SerialMon и попробовать переслать сообщение, то все норм(кто бы сомневался), далее интереснее, если снова открыть мою программу, и из нее отправить сообщение то все приходит очень даже правильно. Если вытащить ком порты (кстати ком порты это Moxa uport 1110, и еще на 1130 пробовал), и вставить обратно, и снова запустить мою программу то опять будет доходить только половина сообщения.
Еще одна интересность: пробовал в дебаге, ставить точку остановки на момент отсылки сообщения         
Код
C++ (Qt)
serial->write(message);
и как не странно сообщение доходило нормальное.

и вот почему..?)


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: kuzulis от Август 30, 2012, 19:49
ХЗ, попробуй QtSerialPort (http://qt-project.org/wiki/QtSerialPort_Russian)

Если из текущего транка будут теже проблемы, то попробуй этот  (https://codereview.qt-project.org/#change,33045)патч.

UPD: хотя это странно, я сначала посетовал на то, что ты делаешь сразу close(),
но библиотека должна была все-равно сбросить/отправить все данные в порт перед закрытием.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Givoi от Август 31, 2012, 07:38
вставил небольшую задержку между записью и закрытием порта - 5 милисекунд, и все работает отлично


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: kuzulis от Август 31, 2012, 09:54
Попробуй вставить вместо задержки flush()

Код
C++ (Qt)
serial->write(message);
serial->flush();
 


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Givoi от Сентябрь 03, 2012, 20:31
флеш не помог, при передачи больших сообщений, даже с задержкой 5 мсек часть сообщения не доходило, немного увеличил до 10 мсек.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Белый пони от Сентябрь 07, 2012, 14:57
Может буффер FIFO на один байт настроить попробовать?


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Bepec от Сентябрь 07, 2012, 15:18
О Моха упоротая :)

Нужно FIFO отключить нафиг. Тогда задержек и разрывов пакетов не будет. Сам мучался.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: kuzulis от Сентябрь 07, 2012, 16:07
Цитировать
Нужно FIFO отключить нафиг.
Каким образом? Код в студию! Пригодится.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Bepec от Сентябрь 07, 2012, 17:29
Открываем студию. Сворачиваем студию. Открываем диспетчер устройств. Тыкаем на MOXA uport. Далее помоему вкладка настройки или параметры и там кнопачка FIFO. Щёлкаем и в открывшемся окне снимаем 2 галки :D Разворачиваем студию :D


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: kuzulis от Сентябрь 07, 2012, 18:57
Не. Для этого должно быть какое то API... Надо позырить через "Free Serial Monitor" все вызовы к драйверу.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Белый пони от Сентябрь 07, 2012, 23:36
Про какую ОС речь-то?

Для линуха я такого API я не нашёл, вот что в how-to пишут:

Цитировать
Note that the interrupt threshold of FIFO buffers (trigger level) may be set at less than 14.  1, 4 and 8 are other possible choices. As of late 2000 there was no way the Linux user could set these directly (setserial can't do it).
http://linux.about.com/od/srl_howto/a/hwtsrl20t03.htm (http://linux.about.com/od/srl_howto/a/hwtsrl20t03.htm)

Так что для Убунты пришлось вручную писать нужные биты прямо в регистры порта. Но это было для "родного" компорта, а не юсб-переходника.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: kuzulis от Сентябрь 08, 2012, 00:12
Речь про винду была.

Хотя интересно, в какое время выстреливает виндовое событие EV_RXCHAR:
каждый раз по приходу одного символа, или через каждые 14 ?
т.е. влияют ли настройки FIFO в панели управления на этот результат?

Аналогично хотелось бы и для *nix узнать: как корреллирует событие от select()
с прерываниями от FIFO. Зависит ли это от драйвера и типа tty?

Хм... Если есть возможность настраивать этот порог из user space - то это было бы хорошо. :)


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Bepec от Сентябрь 08, 2012, 12:52
Ну насколько я знаю (а по драйверам знаю мало :D ), FIFO как раз замедляет приём/передачу. И приходят байты не сразу, а после накопления этого чортового буфера :) Потому могут резаться пакеты, исчезать байты. Общение с устройствами Real-Time практически невозможно :) Куча ошибок вылазит на приёме.


Название: Re: Потеря части сообщения при передаче через ком порт, QSerialPort
Отправлено: Белый пони от Сентябрь 08, 2012, 22:35
Ну насколько я знаю (а по драйверам знаю мало :D ), FIFO как раз замедляет приём/передачу. И приходят байты не сразу, а после накопления этого чортового буфера :) Потому могут резаться пакеты, исчезать байты. Общение с устройствами Real-Time практически невозможно :) Куча ошибок вылазит на приёме.
Байты приходят либо после накопления буфера, либо после паузы. Т.е. если в течение времени (длительность прихода одного байта) ничего не придёт, что буфер выплюнет то что есть (сгенерирует прерывания на чтение).
От ошибок он скорее спасает, т.к. не даёт потеряться байтам, которые комп не успеет прочитать, выполняя другие задачи.


По поводу связи прерываний и select'а.
Насколько я понял по своим программам, он он реагирует именно на прерывания от uart'а. Т.е. если в буфере уже есть что-то, но полностью он ещё не заполнен, то селект ничего не прочитает.
Но как при этом проявляет себя драйвер или ОС, не выделяет ли сам линукс/qnx дополнительные буферы, я сам бы рад узнать)