Почему у QTSerialPort заканчиваются байты внутри потока?
У меня есть тема, похожая на это. Проблема, с которой я столкнулся, заключается в том, что через несколько секунд
serial_port->bytesAvailable()
показывает
0
после того, как я прочитал все байты, и я думаю, что это связано с потоками, вызывающими эту проблему.
Вопрос:
Есть ли правильный способ орудия
QSerialPort
внутри потока или вне потока? Что ты думаешь я должен сделать?
Код:
USB_message_available_thread::USB_message_available_thread(QSerialPort* serial_port, J1939* j1939, uint8_t* length_of_usb_message) : serial_port(serial_port), j1939(j1939), length_of_usb_message(length_of_usb_message) {
}
void USB_message_available_thread::run(){
while(1){
if(serial_port->isOpen()){
if(serial_port->bytesAvailable() >= *length_of_usb_message){
switch(*length_of_usb_message){
case USB_J1939_MESSAGE_BYTES_FROM_STM32:
Open_SAE_J1939_Listen_For_Messages(j1939);
break;
case USB_MEASUREMENT_MESSAGE_BYTES_FROM_STM32:
break;
case USB_NOT_READ_MESSAGES_FROM_STM32:
serial_port->flush(); /* Flush the USB port from bytes */
break;
}
}
}
msleep(10);
}
}
/* QT includes */
#include <QThread>
#include <QSerialPort>
/* Project includes */
#include "Window/Main/UI/UI_tools/Communication/J1939/Open_SAE_J1939/Open_SAE_J1939.h"
class USB_message_available_thread : public QThread {
public:
USB_message_available_thread(QSerialPort* serial_port, J1939* j1939, uint8_t* length_of_usb_message);
private:
/* Constructor fields */
QSerialPort* serial_port;
J1939* j1939;
uint8_t* length_of_usb_message;
/* Logic */
void run();
};
1 ответ
да. Темы +
QSerialPort
плохая комбинация.
Намного лучше использовать
readyRead
как было предложено выше. Вот простой пример USB-связи с
slots
. Для каждого байта, который я отправляю в порт USB, функция
bytesAvailable()
будет вызываться напрямую, как слушатель. Но я проверяю, какой длины должно быть сообщение USB, потому что каждое сообщение USB (в моем случае) имеет разную длину.
#include "usb_handling.h"
/* Private includes */
#include "Tools/Communication/J1939/Hardware/CAN_Network/CAN_to_USB/can_to_usb.h"
#include "../usb_message_sizes.h"
#include "../../J1939/Open_SAE_J1939/Open_SAE_J1939.h"
USB_handling::USB_handling(J1939* j1939) : j1939(j1939) {
/* Create serial port */
serial_port = new QSerialPort();
serial_port_info = new QSerialPortInfo();
/* Save serial port pointer to CAN source file */
QT_USB_set_serial_handler(serial_port);
/* Start a listener for every time this application got a byte, then the function bytesAvailable is going to run */
connect(serial_port, &QSerialPort::readyRead, this, &USB_handling::bytesAvailable);
}
QStringList USB_handling::get_port_names(){
QStringList port_names;
QList<QSerialPortInfo> port_info = serial_port_info->availablePorts();
for (int i = 0; i < port_info.length(); i++)
if (port_info.at(i).isBusy() == false)
port_names.append(port_info.at(i).portName());
return port_names;
}
bool USB_handling::connect_to_usb(const QString& port_name, const qint32 baudrate, QSerialPort::DataBits data_bits, QSerialPort::Parity parity, QSerialPort::StopBits stop_bits, QSerialPort::FlowControl flow_control){
serial_port->setPortName(port_name);
serial_port->setBaudRate(baudrate);
serial_port->setDataBits(data_bits);
serial_port->setParity(parity);
serial_port->setStopBits(stop_bits);
serial_port->setFlowControl(flow_control);
if(serial_port->open(QIODevice::ReadWrite)){
length_of_usb_message = USB_NOT_READ_MESSAGES_FROM_STM32;
return true;
}else{
return false;
}
}
void USB_handling::disconnect_from_usb(){
serial_port->close();
}
void USB_handling::bytesAvailable(){
if(serial_port->bytesAvailable() >= length_of_usb_message){
switch(length_of_usb_message){
case USB_J1939_MESSAGE_BYTES_FROM_STM32:
Open_SAE_J1939_Listen_For_Messages(j1939);
break;
case USB_MEASUREMENT_MESSAGE_BYTES_FROM_STM32:
break;
case USB_NOT_READ_MESSAGES_FROM_STM32:
serial_port->flush(); /* Flush the USB port from bytes */
break;
}
}
}
#ifndef USB_HANDLING_H
#define USB_HANDLING_H
/* QT includes */
#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
/* Project includes */
#include "../../J1939/Open_SAE_J1939/Structs.h"
class USB_handling : public QObject {
Q_OBJECT
public:
USB_handling(J1939* j1939);
QStringList get_port_names();
bool connect_to_usb(const QString& port_name, const qint32 baudrate, QSerialPort::DataBits data_bits, QSerialPort::Parity parity, QSerialPort::StopBits stop_bits, QSerialPort::FlowControl flow_control);
void disconnect_from_usb();
uint8_t length_of_usb_message;
private:
/* Constructor fields */
J1939* j1939;
QSerialPortInfo* serial_port_info;
QSerialPort* serial_port;
private slots:
void bytesAvailable();
};
#endif // USB_HANDLING_H