Russian Qt Forum
Ноябрь 25, 2024, 09:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Потеря части сообщения при передаче через ком порт, QSerialPort  (Прочитано 10974 раз)
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);
и как не странно сообщение доходило нормальное.

и вот почему..?)
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Август 30, 2012, 19:49 »

ХЗ, попробуй QtSerialPort

Если из текущего транка будут теже проблемы, то попробуй этот патч.

UPD: хотя это странно, я сначала посетовал на то, что ты делаешь сразу close(),
но библиотека должна была все-равно сбросить/отправить все данные в порт перед закрытием.
« Последнее редактирование: Август 30, 2012, 19:56 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Givoi
Гость
« Ответ #2 : Август 31, 2012, 07:38 »

вставил небольшую задержку между записью и закрытием порта - 5 милисекунд, и все работает отлично
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Август 31, 2012, 09:54 »

Попробуй вставить вместо задержки flush()

Код
C++ (Qt)
serial->write(message);
serial->flush();
 
Записан

ArchLinux x86_64 / Win10 64 bit
Givoi
Гость
« Ответ #4 : Сентябрь 03, 2012, 20:31 »

флеш не помог, при передачи больших сообщений, даже с задержкой 5 мсек часть сообщения не доходило, немного увеличил до 10 мсек.
Записан
Белый пони
Гость
« Ответ #5 : Сентябрь 07, 2012, 14:57 »

Может буффер FIFO на один байт настроить попробовать?
Записан
Bepec
Гость
« Ответ #6 : Сентябрь 07, 2012, 15:18 »

О Моха упоротая Улыбающийся

Нужно FIFO отключить нафиг. Тогда задержек и разрывов пакетов не будет. Сам мучался.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Сентябрь 07, 2012, 16:07 »

Цитировать
Нужно FIFO отключить нафиг.
Каким образом? Код в студию! Пригодится.
Записан

ArchLinux x86_64 / Win10 64 bit
Bepec
Гость
« Ответ #8 : Сентябрь 07, 2012, 17:29 »

Открываем студию. Сворачиваем студию. Открываем диспетчер устройств. Тыкаем на MOXA uport. Далее помоему вкладка настройки или параметры и там кнопачка FIFO. Щёлкаем и в открывшемся окне снимаем 2 галки Веселый Разворачиваем студию Веселый
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #9 : Сентябрь 07, 2012, 18:57 »

Не. Для этого должно быть какое то API... Надо позырить через "Free Serial Monitor" все вызовы к драйверу.
Записан

ArchLinux x86_64 / Win10 64 bit
Белый пони
Гость
« Ответ #10 : Сентябрь 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

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

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Сентябрь 08, 2012, 00:12 »

Речь про винду была.

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

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

Хм... Если есть возможность настраивать этот порог из user space - то это было бы хорошо. Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Bepec
Гость
« Ответ #12 : Сентябрь 08, 2012, 12:52 »

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

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


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


Страница сгенерирована за 0.104 секунд. Запросов: 22.