QSerialPort вызывает остановку программы (бесконечный цикл?) При открытии устройства

Я хочу написать на последовательном устройстве. К сожалению, у меня такое чувство, что QSerialPort неправильно реализован в Linux. В отличие от других методов (python) я получаю! Иногда! зависание программы, когда я пытаюсь позвонить:

serial.open(QIODevice::ReadWrite)

Я использую пример из http://qt-project.org/wiki/QtSerialPort (увидеть ниже). QSerialPortInfo работает правильно, так что я могу искать свое устройство, прежде чем открыть его. Проблема появилась во всех сериях Qt 5. *. В настоящее время я использую бета-версию 5.3 из репозитория OpenSuse. Другие инструменты или методы доказывают, что устройство работает (Windows или Python).

// Example use QSerialPortInfo
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
qDebug() << "Name        : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();

// Example use QSerialPort
QSerialPort serial;
serial.setPort(info);
if (serial.open(QIODevice::ReadWrite)) // Hang of the program
serial.close();
}

Рабочий скрипт на python:

com_port = 4
baud_rate = '9600'
pySerial = serial.Serial(com_port, baud_rate)

Редактировать:
Я тестировал с отладчиком. Кажется, проблема Qt 5 по крайней мере с Linux. Похоже, связано с блокировкой устройства.

3

Решение

Я не знаю, на что жалуется мистер Папп; Я смог воспроизвести вашу проблему без дополнительной информации.

В Linux, если процесс Qt с открытым экземпляром QSerialPort завершается ненормально или в противном случае экземпляр QSerialPort не уничтожается при выходе из процесса, тогда файл блокировки зависает и может вызвать проблему. Устаревший файл блокировки не должен вызывать эту проблему; файл блокировки содержит PID разбившегося приложения, и новый экземпляр приложения должен распознать, что не существует процесса с этим PID, и удалить блокировку непосредственно перед созданием новой. strace будет показывать вам файл блокировки, о котором идет речь, с увеличением времени отката, поскольку новый процесс неоднократно проверяет, был ли удален устаревший файл блокировки или что-то еще. Итак, удалите файл (например, /var/lock/LCK..ttyS0); вы будете владельцем файла блокировки, если вы запустили приложение, которое зависло.

Случайное примечание: если вы используете QSerialPort в Python через PyQt5 (что, кстати, работает!), Убедитесь, что вы явно удалили экземпляр QSerialPort до выхода из интерпретатора Python. Если вы управляете портом в IPython, то перед выходом выполните «% xdel portobject».

Это тупой обходной путь, но при условии, что вы используете какой-то другой механизм, чтобы гарантировать, что у вас нет двух экземпляров вашей программы, работающих и использующих один и тот же порт — или, если вам просто все равно, — вы можете удалить строку кода этот файл блокировки до открытия порта.

ИМХО, во-первых, Qt не должен эмулировать абсолютно бесполезную защиту от состояния няньки в стиле Windows. Я могу sudo rm -rf /, и это происходит! Я могу даже RM последовательный порт. Учитывая такую ​​беспрепятственную, первобытную, богоподобную силу, я должен иметь возможность открывать последовательный порт всякий раз, когда мне угодно …

4

Другие решения

Класс пытается получить блокировку для последовательного порта. Линия lockFileScopedPointer->lock(); в bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
Возможно, приложение было запущено от имени пользователя root, и файл блокировки недоступен, если приложение запускается от имени другого пользователя. Запустите strace, чтобы проверить.

3

По вопросам рекламы [email protected]