场景
cpu架构: arm64 天嵌TQA133
系统:ubuntu18.04
Qt版本:Qt5.9.0
波特率: 115200
代码逻辑
初始化
m_serial = new QSerialPort();
if(!m_serial)
{
qDebug("error:m_serialis null");
return -1;
}
m_serial->setPortName(FileSystem::UART_EFFECT()); // 串口设备
#ifdef ARM_A40I
m_serial->setBaudRate(57600);
#endif
#ifdef ARM_TQA133
m_serial->setBaudRate(QSerialPort::Baud115200);
#endif
m_serial->setDataBits(QSerialPort::Data8);
m_serial->setParity(QSerialPort::OddParity); //因为数据发送是一个字节一个字节发送的,所以需要启用奇偶校验否则收到的数据会多出一些莫名其妙的字符
m_serial->setStopBits(QSerialPort::OneStop);
m_serial->setFlowControl(QSerialPort::NoFlowControl);
if (m_serial->open(QIODevice::ReadWrite)) {
// 连接信号和槽
connect(m_serial, &QSerialPort::readyRead, this, &EffectSerialThread::readData);
qDebug() << "Open effect serialport is ok";
} else {
qDebug() << "Open effect serialport is error";
return 0;
}接收逻辑
void EffectSerialThread::readData()
{
auto date = m_serial->readAll();
}复现方式
每50毫秒通过使用QSerialPort通过串口向设备发送数据,当设备有数据回复过来时会触发readData槽函数,然后在槽函数中读取所有数据。
程序运行起来后十几秒到一分钟左右程序就会崩溃,从生成的core文件来看崩溃在m_serial->readAll()之中。
修复方式
取消信号槽,数据的接收不再放在槽函数。
主动通过判断m_serial->atEnd()的返回值决定是否读取数据
void EffectSerialThread::run()
{
InitSerial();
m_is_run = true;
while(m_is_run)
{
while (!m_serial->atEnd()) {
auto data = m_serial->read(512);
m_data_buff.append(data);
}
if (!m_data_buff.isEmpty()) {
// SPG_INFO("data buff size:" << m_data_buff.size())
readData();
}
if((!mTxData_Queue.empty() || !mTxVersion_Queue.empty())&&m_bUartComplete)
{
if (m_is_init) {
mutex.lock();
if (mTxData_Queue.empty()) {
mutex.unlock();
msleep(50);
continue;
}
QByteArray data = mTxData_Queue.dequeue();//出队
mutex.unlock();
SendSerialData(data);
} else {
m_version_mutex.lock();
if (mTxVersion_Queue.empty()) {
m_version_mutex.unlock();
msleep(50);
continue;
}
auto data = mTxVersion_Queue.dequeue();
m_version_mutex.unlock();
SendSerialData(data);
}
continue;
}
msleep(50);
}
}