1. 写在前面
唔… 在公司睡了三天地板, 总算搞出来了…
环境: Qt5.14, Win10系统
2. 建立插件工程
-
选择C++ Library
-
创建路径
-
建立cpp和头文件
-
配置编译工具
-
设置为Git
-
生成工程文件.pro
3. 逻辑代码移植
核心代码逻辑额…
作为一名熟练的
Ctrl
+
C
和
Ctrl
+
V
操作工(面向开源的Ctrl + C Ctrl + V工程师), 这一点我就不卖弄了… 抄VectorCAN的逻辑就好了 ^v^具体的还需要看用的CAN盒子, 厂家提供的二次开发的dll文件;
用过周立功和广成科技这两家的CAN盒子, 本以为可以通用上, 结果发现广成科技的CAN盒子驱动层的dll似乎是在周立功家的基础上再封装了一次; 无奈之下只好重写一份;关于具体的逻辑
3.1. 流程
loadDriver
==>
interfaces
==>
canCreate
==>
openCAN
==>
setupChannel
==>
setBaudRate
==>
startCAN
==>
startRead
==>
startWrite
3.2. 接收
开一个1ms~10ms的定时器, 定时接收报文插入接收队列;
3.3. 发送
发送队列由device接管, 插件这边只管插入发送队列, 后续通过定时器为0, 也就是尽可能快的发送出去;
- main.cpp
主要是查找有效的设备列表availableDevices和生成设备createDevice
// main.cpp
#include "gcusbcaniicbackend.h"
#include <QtSerialBus/qcanbus.h>
#include <QtSerialBus/qcanbusdevice.h>
#include <QtSerialBus/qcanbusfactory.h>
#include <QtCore/qloggingcategory.h>
#include "StatusErrorsDefine.h"
#include "debugLog.h"
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_GCUSBCANIIC, "qt.canbus.plugins.gcusbcaniic")
class GCUsbCanBusPlugin : public QObject, public QCanBusFactoryV2
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json")
Q_INTERFACES(QCanBusFactoryV2)
public:
QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override
{
if (Q_UNLIKELY(!GCUsbCANIICBackend::canCreate(errorMessage)))
return QList<QCanBusDeviceInfo>();
// QString strDes = "About to return interfaces";
// QString strFun = "availableDevices";
// DebugLogMethod::DebugLog(strFun, strDes);
// QString strWarn = QString("%1 Warning!").arg(strDes);
// QString strCrit = QString("%1 Critical!").arg(strDes);
// qCWarning(QT_CANBUS_PLUGINS_GCUSBCANIIC, "%ls", qUtf16Printable(strWarn));
// qCritical(QT_CANBUS_PLUGINS_GCUSBCANIIC, "%ls", qUtf16Printable(strCrit));
return GCUsbCANIICBackend::interfaces();
}
QCanBusDevice *createDevice(const QString &interfaceName, QString *errorMessage) const override
{
QString errorReason;
if (Q_UNLIKELY(!GCUsbCANIICBackend::canCreate(&errorReason))) {
qCWarning(QT_CANBUS_PLUGINS_GCUSBCANIIC, "%ls", qUtf16Printable(errorReason));
if (errorMessage)
*errorMessage = errorReason;
return nullptr;
}
// QString strDes = "About to return device";
// QString strFun = "createDevice";
// DebugLogMethod::DebugLog(strFun, strDes);
auto device = new GCUsbCANIICBackend(interfaceName);
return device;
}
};
QT_END_NAMESPACE
#include "main.moc"
- backend.h
// GCUsbCANIICBackend
#ifndef GCUSBCANIICBACKEND_H
#define GCUSBCANIICBACKEND_H
#include "GCUsbCANIIC_global.h"
#include <QtSerialBus/qcanbusframe.h>
#include <QtSerialBus/qcanbusdevice.h>
#include <QtSerialBus/qcanbusdeviceinfo.h>
#include <QtCore/qvariant.h>
#include <QtCore/qvector.h>
#include <QtCore/qlist.h>
#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
class GCUsbCANIICBackendPrivate;
Q_DECLARE_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_GCUSBCANIIC)
//class GCUSBCANIIC_EXPORT GCUsbCANIICBackend
class GCUsbCANIICBackend : public QCanBusDevice
{
Q_OBJECT
Q_DECLARE_PRIVATE(GCUsbCANIICBackend)
Q_DISABLE_COPY(GCUsbCANIICBackend)
public:
explicit GCUsbCANIICBackend(const QString &name, QObject *parent = nullptr);
~GCUsbCANIICBackend();
bool open() override;
void close() override;
void setConfigurationParameter(int key, const QVariant &value) override;
bool writeFrame(const QCanBusFrame &newData) override;
QString interpretErrorFrame(const QCanBusFrame &errorFrame) override;
static bool canCreate(QString *errorReason);
static QList<QCanBusDeviceInfo> interfaces();
private:
GCUsbCANIICBackendPrivate * const d_ptr; // the name after GCUsbCANIICBackend##Private is believed to used the d_ptr pointer
};
QT_END_NAMESPACE
#endif // GCUSBCANIICBACKEND_H
4. 后话
能用就好哈 ^w^