Qt之modbus_slave例程的底层串口数据分析
一. 参考网址
2. How to redirect qDebug, qWarning, qCritical etc output?
二. 问题
1. 如何查看slave底层收到的主机发送的消息和回复的消息?
解决办法:在main.cpp代码中取消注释
注:QLoggingCategory::setFilterRules函数不能重复使用,其只能最后一条语句起作用,如
.......
QLoggingCategory::setFilterRules("qt.modbus = true"); //此行代码不会起作用
QLoggingCategory::setFilterRules("qt.modbus.lowlevel = true");
.......
三. 代码分析
1. 参考代码目录
例程:Qt\Examples\Qt-5.15.2\serialbus\modbus\slave
Qt底层源码:Qt\5.15.2\Src\qtserialbus\src\serialbus
2. 从上到下的层次关系
2.1 代码调用关系
MainWindow::MainWindow(QWidget *parent) //mainwindow.cpp
onCurrentConnectTypeChanged(0); //mainwindow.cpp
modbusDevice = new QModbusRtuSerialSlave(this); //mainwindow.cpp
Q_DECLARE_PRIVATE(QModbusRtuSerialSlave) //位于qt底层源码目录:qmodbusrtuserialslave.h
class QModbusRtuSerialSlavePrivate : public QModbusServerPrivate //位于qt底层源码目录:qmodbusrtuserialslave_p.h
setupSerialPort() //位于qt底层源码目录:qmodbusrtuserialslave_p.h
2.2 在setupSrialPort()函数中定义了信号与槽函数,用于接收串口数据
// qmodbusrtuserialslave_p.h
void setupSerialPort() { Q_Q(QModbusRtuSerialSlave); m_serialPort = new QSerialPort(q); QObject::connect(m_serialPort, &QSerialPort::readyRead, q, [this]() { //信号与槽函数
m_requestBuffer += m_serialPort->read(size); //读取串口数据 qCDebug(QT_MODBUS_LOW) << "(RTU server) Received ADU:" << adu.rawData().toHex(); //打印接收到的串口数据ADU格式(完整的modbus协议)
qCDebug(QT_MODBUS) << "(RTU server) Request PDU:" << req; //校验成功后,打印PDU格式数据
response = q->processRequest(req); //获取到响应的数据 PDU格式
qCDebug(QT_MODBUS) << "(RTU server) Response PDU:" << response; //打印需要响应的PDU格式数据
const QByteArray result = QModbusSerialAdu::create(QModbusSerialAdu::Rtu, q->serverAddress(), response); //生成ADU格式数据,完整的modbus协议
qCDebug(QT_MODBUS_LOW) << "(RTU server) Response ADU:" << result.toHex(); //打印完整的modbus协议响应数据,ADU格式
qint64 writtenBytes = m_serialPort->write(result); //发送数据
}
......
}
四. 开启底层串口的数据调试打印信息
1. Q_DECLARE_LOGGING_CATEGORY , 参考文件:qmodbusrtuserialslave_p.h
2. Q_LOGGING_CATEGORY, 参考文件:qmodbusdevice.cpp
3. 文件:main.cpp