Qt CAN 总线
控制器局域网(CAN)是一种车辆总线标准,旨在允许微控制器和设备在没有主机的应用中相互通信。
概述
CAN 总线是一种基于报文的协议,最初设计用于汽车内的多路复用电线,但也用于许多其他场合。
CAN 总线 API 提供了一些访问 CAN 设备的通用 API:
- QCanBus 提供从选定插件创建 的 API。QCanBusDevice
- QCanBusDeviceInfo 提供有关可用 CAN 设备的信息。
- QCanBusDevice 提供直接访问 CAN 设备的 API。
- QCanBusFrame 定义 CAN 框架,可从 中写入和读取。QCanBusDevice
从 Qt 6.5 开始,该模块提供了从原始 CAN 框架中解码实际信号值的 API,还可将用户数据编码到 CAN 框架中:
- QCanSignalDescription 提供处理 CAN 信号的规则。
- QCanMessageDescription 提供处理 CAN 报文的规则。一个报文描述通常包含多个信号描述。
- QCanUniqueIdDescription 提供处理 CAN 帧内唯一标识符的规则。
- QCanFrameProcessor 使用 、 和 类提供的描述来编码或解码 CAN 帧。QCanMessageDescription QCanSignalDescription QCanUniqueIdDescription
- QCanDbcFileParser 提供从 DBC 文件中提取报文描述的 API。
注: 所有用于编码和解码 CAN 帧的 API 都是试验性的,可能会有更改。
CAN 总线插件
多家供应商提供的 CAN 设备具有不同的访问 API。QtSerialBus 模块支持以下几组 CAN 总线插件:
供应商 | 插件(关键字) | 简要说明 |
---|---|---|
通过 Linux 套接字连接 CAN | SocketCAN(socketcan ) | 使用 Linux 插座和开源驱动程序的 CAN 总线插件。 |
通过 SAE J2534 直通 CAN | PassThruCAN(passthrucan ) | 使用 SAE J2534 Pass-Thru 接口的 CAN 总线插件。 |
SYS TEC 电子 | SystecCAN(systeccan ) | 使用 SYS TEC CAN 适配器的 CAN 总线后端。 |
PEAK 系统 | PeakCAN(peakcan ) | 使用 PEAK CAN 适配器的 CAN 总线插件。 |
MHS Elektronik | TinyCAN(tinycan ) | 使用 MHS CAN 适配器的 CAN 总线插件。 |
Vector Informatik | VectorCAN(vectorcan ) | 使用 Vector CAN 适配器的 CAN 总线插件。 |
虚拟 CAN 接口 | VirtualCAN(virtualcan ) | 使用虚拟 TCP/IP 连接的 CAN 总线插件。 |
实现自定义 CAN 插件
如果 Qt 提供的插件不适合所需的目标平台,则可以实施自定义 CAN 总线插件。实施方法与 Qt 插件的标准实施方法相同。自定义插件必须部署到$QTDIR/plugins/canbus
。
每个插件必须定义一个键,用于加载插件。这是通过一个小的 json 文件完成的。例如,socketcan 插件使用以下plugin.json
:
{ "Key": "socketcan" }
QCanBus::createDevice QCanBus 使用 QCanBusFactoryV2 接口加载和实例化插件,每个插件都必须将该接口作为中心入口点来实现。该接口充当工厂,其唯一目的是返回一个 实例。上述接口名称通过工厂的 () 方法传递。以下是QCanBusDevice QCanBusFactory::createDevicesocketcan插件的工厂实现:
class SocketCanBusPlugin : public QObject, public QCanBusFactory { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QCanBusFactory" FILE "plugin.json") Q_INTERFACES(QCanBusFactory) public: QList<QCanBusDeviceInfo> availableDevices(QString *errorMessage) const override { Q_UNUSED(errorMessage); return SocketCanBackend::interfaces(); } QCanBusDevice *createDevice(const QString &interfaceName, QString *errorMessage) const override { Q_UNUSED(errorMessage); auto device = new SocketCanBackend(interfaceName); return device; } };
下一步是提供QCanBusDevice 的实现。至少必须实现以下纯虚拟函数:
- QCanBusDevice::open()
- QCanBusDevice::close()
- QCanBusDevice::writeFrame()
- QCanBusDevice::interpretErrorFrame()
open() 和close() 方法分别与QCanBusDevice::connectDevice() 和QCanBusDevice::disconnectDevice() 结合使用。有关实现细节,请查阅函数文档。
QCanBusDevice::writeFrame() 负责进行正确性检查,如QCanBusFrame 的有效性以及设备是否仍在连接。如果检查通过,则将帧写入 CAN 总线。成功后,它将发出QCanBusDevice::framesWritten() 信号;否则将调用QCanBusDevice::setError() 并给出相应的错误信息。该函数也可用于实现异步写入操作。插件实现者有责任在适当的时间发出适当的信号。
最后但并非最不重要的一点是,QCanBusDevice::interpretErrorFrame 提供了一种方便的方法,可将 CAN 总线错误帧的内容转换为人类可读的错误字符串。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.