24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
1

QSerialPort зависает при попытки закрытии порта

17.12.2014, 09:35. Показов 4616. Ответов 22
Метки нет (Все метки)

Доброго времени суток!
ПО: Qt 5.3.2, Mingw 4.8.2, windows 7 32бит. Подключаемое устройство USB FTDI.

Бага засветилась в QTBUG-41052, но решения там нет.

Проблема вот в чем:
Подключаем устройство, работаем с ним или вообще ни чего не делаем (разницы нет), в подключенном состоянии выдергиваем шнур. Далее пытаемся закрыть подключение. Вот тут программа и зависает. Причем если воткнуть прибор обратно, подключение закрывается, и программа снова в рабочем состоянии.

Закрытие порта:
C++ (Qt)
1
2
3
4
if ( m_serial_port->isOpen() )
{
     m_serial_port->close(); 
}
Дальше обернул
C++ (Qt)
1
QSharedPointer< QSerialPort > m_serial_port;
И попробовал удалить m_serial_port (reset), абсолютно тоже самое. Ловил ошибки QSerialPort::PermissionError и другие тоже. Пробовал закрывать, удалять, очищать буферы ни какого толку. Хоть на boost::asio переходи, там такого не было.
Есть подозрение, что это все таки бага Qt.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.12.2014, 09:35
Ответы с готовыми решениями:

QSerialPort - подключение при статической сборке
Всем привет. Установил Qt 5.1, решил понасиловать COM-порт. Как я понимаю, с библиотекой...

Чтение из COM порта, При чтении из порта зависает read()
Каждому рано или поздно приходится программировать com порт. Вот и мой черед пришол. Я ужу умею:...

Ошибка при закрытии и переоткрытии COM порта
Доброго времени суток! Может быть кто сталкивался... Использую для работы с COM портами код в...

Отследить событие закрытия сокета, при закрытии порта через iptables
Друзья, возникла ситуация, имеется linux-приложение, которое берет из входящей очереди сообщения и...

22
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 09:58 2
На Qt5.4 проблема присутствует?
0
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 10:08  [ТС] 3
Shtirliz72, Там проблема решена?

Добавлено через 6 минут
Shtirliz72, Не знаю. Проверю...
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 10:11 4
Это у тебя в обработке сигнала QSerialPort::error?

Добавлено через 46 секунд
Цитата Сообщение от IndyStar Посмотреть сообщение
Shtirliz72, Не знаю. Проверю...
Подожди. Ответь на вопрос чуть выше, о том, где ты пытаешься закрыть соединение.
0
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 10:21  [ТС] 5
Shtirliz72,
Зависание тут m_serial_port->close(), при отключенном устройстве конечно. Дальше close код "не идет".
Закрыть соединение по кнопке на форме.
Где код
C++ (Qt)
1
2
3
4
if ( m_serial_port->isOpen() )
{
     m_serial_port->close(); 
}
В обработчик error заходит.
Что пробовал:
1) Закрыть соединение.
2) Просто удалить по кнопке.
3) Удалить в обработчике ошибок.

Соединение тупо не закрывается, подключишь устройство обратно и только после этого происходит разрыв.
А вообще ошибка QSerialPort::PermissionError в момент закрытия (отказ в доступе).
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 10:34 6
Цитата Сообщение от IndyStar Посмотреть сообщение
Зависание тут m_serial_port->close(), при отключенном устройстве конечно. Дальше close код "не идет".
Я о другом - у тебя идёт обработка ошибки QSerialPort? У тебя поставлен обработчик на его error сигнал?

Добавлено через 2 минуты
m_serial_port.connect(SIGNAL(error(QSerialPort::SerialPortEr ror)), <> ,SLOT(_функция_обработчик(QSerialPort::SerialPortError))) у тебя есть?
0
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 10:35  [ТС] 7
Shtirliz72, Да, обработчик стоит. Ошибка QSerialPort::PermissionError.
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 10:36 8
Цитата Сообщение от IndyStar Посмотреть сообщение
Shtirliz72, Да, обработчик стоит. Ошибка QSerialPort::PermissionError.
Приведи здесь код этого обработчика.

Добавлено через 29 секунд
Или он у тебя при вытыкании устройства не вызывается?
0
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 10:40  [ТС] 9
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void serial_port::handle_error(QSerialPort::SerialPortError error)
{
    if (error == QSerialPort::ReadError)
    {
        qDebug() << QObject::tr("An I/O error occurred while reading the data from port %1, error: %2").arg(m_serial_port->portName()).arg(m_serial_port->errorString());
        return;
    }
    if (error == QSerialPort::ResourceError)
    {
        qDebug() << QObject::tr("ResourceError: port %1, Error - %2").arg( m_serial_port->portName() ).arg( m_serial_port->errorString() );
        disconnect();
        return;
    }
    if (error == QSerialPort::WriteError)
    {
        qDebug() << "QSerialPort::WriteError";
    }
    if (error == QSerialPort::PermissionError)
    {
        qDebug() << "QSerialPort::PermissionError";
    }
 
    qDebug() << QObject::tr("Error № %3 port %1: %2").arg( m_serial_port->portName() ).arg( m_serial_port->errorString() ).arg(error);
}
Тут уже намудрил немного.

Shtirliz72

Вызывается. В момент m_serial_port->close() ошибка QSerialPort::PermissionError

Добавлено через 3 минуты
Shtirliz72, Опа извини. Я попробовал второй раз вызвать m_serial_port->close() при QSerialPort::PermissionError и все начало работать. Сейчас несколько раз проверю.
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 10:41 10
Цитата Сообщение от IndyStar Посмотреть сообщение
Тут уже намудрил немного.
serial_port - это что? наследник QSerialPort или сторонний класс?
1
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 10:42  [ТС] 11
serial_port да это временно класс назвал для тестов где и юзаю QSerialPort
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 10:42 12
Лучший ответ Сообщение было отмечено IndyStar как решение

Решение

Цитата Сообщение от IndyStar Посмотреть сообщение
Shtirliz72, Опа извини. Я попробывал второй раз вызвать m_serial_port->close() при QSerialPort::PermissionError и все начало работать. Сейчас несколько раз проверю.
Ага, вот именно это самое я тебе и хотел посоветовать.
1
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 13:02  [ТС] 13
Да работает. Блин что со мной не так

Добавлено через 2 часа 17 минут
Вернулся после обеда. Ошибка все еще происходит!
Соединились. Далее кидаем в порт данные, по таймеру раз в 100 мс, получаем данные. В этот момент выдергиваем устройство. Данные по таймеру продолжают отправляться в порт (ни каких ошибок нет!). Далее жмем отключиться. Тут то и происходит вышеописанное зависание. На Qt 5.4 тоже самое.
Значит нужно:
Либо как-то отследить отключение. Либо что-то сбросить/очистить перед отключением.

Есть варианты?
0
202 / 148 / 5
Регистрация: 14.03.2013
Сообщений: 784
17.12.2014, 13:09 14
Цитата Сообщение от IndyStar Посмотреть сообщение
Либо как-то отследить отключение. Либо что-то сбросить/очистить перед отключением.
Правда я работал с Ethernet-ом но думаю тут так же. Отправлять тестовые пакеты и ждать получения определенного пакета и поставить таймер через какое время отправлять. Если конечно приемная часть Ваша или ее можно переписать.
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 13:11 15
Цитата Сообщение от IndyStar Посмотреть сообщение
Вернулся после обеда. Ошибка все еще происходит!
Соединились. Далее кидаем в порт данные, по таймеру раз в 100 мс, получаем данные. В этот момент выдергиваем устройство. Данные по таймеру продолжают отправляться в порт (ни каких ошибок нет!). Далее жмем отключиться. Тут то и происходит вышеописанное зависание. На Qt 5.4 тоже самое.
То есть сигнал QSerialPort::error при этом не генерируется и слот обработчика этого сигнала в твоём классе не вызывается, я тебя правильно понимаю?
Цитата Сообщение от IndyStar Посмотреть сообщение
Есть варианты?
Вначале мне надо понять, что у тебя там конкретно происходит, потом может какой-либо совет дам.
1
202 / 148 / 5
Регистрация: 14.03.2013
Сообщений: 784
17.12.2014, 13:15 16
Цитата Сообщение от IndyStar Посмотреть сообщение
Либо как-то отследить отключение. Либо что-то сбросить/очистить перед отключением.
При разрыве провода ничего не происходит (опыт с QTCPServer) - то есть сигнал с ошибкой не срабатывает.
А вот если воткнуть провод обратно - появляется ошибка.
По этому наверно надо отправлять какие то короткие пакеты на проверку.
Допустим запрашивать состояние устройства - если пакет с состоянием не пришел за определенное время то значит разрыв.
1
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 13:16  [ТС] 17
Bmg113, Пока смотрю в сторону waitForBytesWritten.

Shtirliz72, Сигнал QSerialPort::error не генерируется при попытки записать в порт при выдернутом устройстве. Генерируется только тогда когда жмем в ручную закрыть порт.
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
17.12.2014, 14:08 18
Цитата Сообщение от IndyStar Посмотреть сообщение
Shtirliz72, Сигнал QSerialPort::error не генерируется при попытки записать в порт при выдернутом устройстве. Генерируется только тогда когда жмем в ручную закрыть порт.
Если сигнал не генерируется, тогда не знаю.
Тогда лучше поступить как советуют выше - отправлять пинг и ожидать понг в течении определённого таймеров времени. Не пришёл - закрывать порт.
1
24 / 24 / 10
Регистрация: 17.12.2014
Сообщений: 72
17.12.2014, 14:50  [ТС] 19
В том то и дело, что порт не закрывается (хоть удаляй объект, все равно как то удерживает).

В общем решения не нашел (Наверно другую либу по serial port возьму. Или нативный код использовать). Хорошо бы грамотно спросить у разработчиков, как быть.

Вопрос:
(Устройство на запрос (write), посылает данные)
Подключаемся к порту. Пишем/читаем данные. Выдергиваем устройство. Пытаемся еще несколько раз отправить данные в порт. После пробуем отключиться (close). Происходит зависание программы. Причем если воткнуть устройство обратно программа продолжает свое выполнение после вызова close().

Вот как то так. Может кто-нибудь запостить Qt-кам?
0
40 / 38 / 7
Регистрация: 21.05.2012
Сообщений: 198
17.12.2014, 15:32 20
В том то и дело, что порт не закрывается (хоть удаляй объект, все равно как то удерживает).
1. Проверь с Terminal Example из примеров от QtSerialPort. То-же будет поведение или нет?
2. Пересобери QtSerialPort из Qt 5.4.1 и проверь снова. Там были сделаны некоторые исправления.
3. Обнови драйвер на FTDI.
4. Сделай отладку. Если оно "зависает" на вызове CloseHandle - то это проблема в драйвере.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.12.2014, 15:32

Программа зависает при закрытии
Здравствуйте У меня следующая проблема - программа зависает при срабатывании frmMain-&gt;Close() ...

Win XP зависает Hibernation при закрытии крышки
Есть ноут. стоит хрюша с 3 сервиспаком В управлении питанием включено использование гибернации...

Клиентская часть постоянно зависает при закрытии потока
Всем доброго времени суток! Написал приложение работающее по TCP. Проблема в том, что при...

Зависает при чтении com порта
Привет всем, подскажите, пожалуйста, у меня есть прибор, с которого я считываю данные каждую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.