Qt - CAN总线
控制器局域网(CAN)是一种车辆总线标准,旨在允许微控制器和设备在没有主机的情况下在应用程序中相互通信。
总览
它是一种基于消息的协议,最初是为汽车内的多路电气布线设计的,但也用于许多其他情况。
CAN Bus API提供了一些通用的API来访问CAN设备:
- QCanBus提供了一个API,可从所选插件创建QCanBusDevice。
- QCanBusDeviceInfo提供有关可用CAN设备的信息。
- QCanBusDevice提供用于直接访问CAN设备的API。
- QCanBusFrame定义了可以从QCanBusDevice写入和读取的CAN帧。
CAN总线插件
多家供应商为CAN设备提供了各种API进行访问。该QtSerialBus模块支持CAN总线插件的设置如下:
供应商 | 插件(密钥) | 简要描述;简介 |
---|---|---|
CAN over Linux sockets |
SocketCAN(socketcan ) |
使用Linux套接字和开源驱动程序的CAN总线插件。 |
CAN via SAE J2534 Pass-Thru |
PassThruCAN(passthrucan ) |
使用SAE J2534 Pass-Thru接口的CAN总线插件。 |
SYS TEC electronic |
SystecCAN(systeccan ) |
使用SYS TEC CAN适配器的CAN总线后端。 |
PEAK-System |
PeakCAN(peakcan ) |
使用PEAK CAN适配器的CAN总线插件。 |
MHS Elektronik |
TinyCAN(tinycan ) |
使用MHS CAN适配器的CAN总线插件。 |
Vector Informatik |
VectorCAN(vectorcan ) |
使用Vector CAN适配器的CAN总线插件。 |
Virtual CAN interface |
VirtualCAN(virtualcan ) |
使用虚拟TCP/IP连接的CAN总线插件。 |
实施自定义CAN插件
如果Qt提供的插件不适合所需的目标平台,则可以实施定制的CAN总线插件。该实现遵循实现Qt插件的标准方法。自定义插件必须部署到$QTDIR/plugins/canbus
。
每个插件必须定义一个Key值,该Key值用于加载插件。这是通过一个小的json文件完成的。例如,socketcan插件使用以下plugin.json
内容:
{
"Key": "socketcan"
}
该Key值必须与CAN总线适配器的接口名称一起传递给QCanBus :: createDevice()。QCanBus使用QCanBusFactoryV2接口加载和实例化插件,每个插件必须将其实现为中央入口点。接口充当工厂,其唯一目的是返回QCanBusDevice实例。上面提到的接口名称是通过QCanBusFactory :: createDevice()工厂方法传递的。以下是socketcan插件的工厂实现:
class SocketCanBusPlugin : 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
{
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 :: interpretedErrorFrame提供了一种方便的方法来将CAN总线错误帧的内容转换为人类可读的错误字符串。
网友评论