Qt CAN-Bus
Ein Controller Area Network (CAN) ist ein Fahrzeugbus-Standard, der es Mikrocontrollern und Geräten ermöglicht, in Anwendungen ohne einen Host-Computer miteinander zu kommunizieren.
Überblick
Es handelt sich um ein nachrichtenbasiertes Protokoll, das ursprünglich für die elektrische Multiplex-Verkabelung in Automobilen entwickelt wurde, aber auch in vielen anderen Zusammenhängen verwendet wird.
Die CAN-Bus-API bietet einige allgemeine APIs für den Zugriff auf CAN-Geräte:
- QCanBus stellt eine API zur Verfügung, um ein QCanBusDevice aus einem ausgewählten Plugin zu erstellen.
- QCanBusDeviceInfo bietet Informationen über verfügbare CAN-Geräte.
- QCanBusDevice bietet eine API für den direkten Zugriff auf das CAN-Gerät.
- QCanBusFrame definiert einen CAN-Frame, der von QCanBusDevice geschrieben und gelesen werden kann.
Ab Qt 6.5 stellt das Modul APIs zur Verfügung, um aktuelle Signalwerte aus rohen CAN-Frames zu dekodieren und auch um Benutzerdaten in CAN-Frames zu kodieren:
- QCanSignalDescription stellt Regeln zur Verarbeitung von CAN-Signalen bereit.
- QCanMessageDescription stellt Regeln für die Verarbeitung von CAN-Nachrichten bereit. Eine Nachrichtenbeschreibung enthält normalerweise mehrere Signalbeschreibungen.
- QCanUniqueIdDescription stellt Regeln zur Verarbeitung eines eindeutigen Identifiers innerhalb eines CAN-Frames zur Verfügung.
- QCanFrameProcessor verwendet Beschreibungen, die von den Klassen QCanMessageDescription, QCanSignalDescription und QCanUniqueIdDescription bereitgestellt werden, um CAN-Frames zu kodieren oder zu dekodieren.
- QCanDbcFileParser bietet eine API zum Extrahieren von Nachrichtenbeschreibungen aus DBC-Dateien.
Hinweis: Alle APIs zur Kodierung und Dekodierung von CAN-Frames sind experimentell und können geändert werden.
CAN-Bus-Plugins
Mehrere Hersteller bieten CAN-Geräte mit unterschiedlichen APIs für den Zugriff an. Das Modul QtSerialBus unterstützt die folgenden CAN-Bus-Plugins:
Hersteller | Plugin (Schlüssel) | Kurzbeschreibung |
---|---|---|
CAN über Linux-Sockel | SocketCAN (socketcan ) | CAN-Bus-Plugin mit Linux-Sockeln und Open-Source-Treibern. |
CAN über SAE J2534 Pass-Thru | PassThruCAN (passthrucan ) | CAN-Bus-Plugin unter Verwendung der SAE J2534 Pass-Thru-Schnittstelle. |
SYS TEC elektronisch | SystecCAN (systeccan ) | CAN-Bus Backend unter Verwendung der SYS TEC CAN-Adapter. |
PEAK-System | PeakCAN (peakcan ) | CAN-Bus-Plugin unter Verwendung der PEAK-CAN-Adapter. |
MHS Elektronik | TinyCAN (tinycan ) | CAN-Bus-Plugin unter Verwendung der MHS-CAN-Adapter. |
Vektor Informatik | VectorCAN (vectorcan ) | CAN-Bus-Plugin unter Verwendung der Vector CAN-Adapter. |
Virtuelle CAN-Schnittstelle | VirtualCAN (virtualcan ) | CAN-Bus-Plugin unter Verwendung einer virtuellen TCP/IP-Verbindung. |
Implementierung eines eigenen CAN-Plugins
Wenn die von Qt zur Verfügung gestellten Plugins für die gewünschte Zielplattform nicht geeignet sind, kann ein eigenes CAN-Bus-Plugin implementiert werden. Die Implementierung folgt dem Standardweg der Implementierung von Qt-Plugins. Das benutzerdefinierte Plugin muss auf $QTDIR/plugins/canbus
deployed werden.
Jedes Plugin muss einen Schlüssel definieren, der zum Laden des Plugins verwendet wird. Dies geschieht über eine kleine json-Datei. Das Socketcan-Plugin verwendet zum Beispiel den folgenden plugin.json
:
{ "Key": "socketcan" }
Dieser Schlüssel muss zusammen mit dem Schnittstellennamen des CAN-Bus-Adapters an QCanBus::createDevice() übergeben werden. QCanBus lädt und instanziiert das Plugin unter Verwendung der Schnittstelle QCanBusFactoryV2, die jedes Plugin als zentralen Einstiegspunkt implementieren muss. Die Schnittstelle fungiert als Fabrik und ihr einziger Zweck ist es, eine QCanBusDevice Instanz zurückzugeben. Der oben erwähnte Schnittstellenname wird über die QCanBusFactory::createDevice()-Methode der Fabrik weitergegeben. Im Folgenden wird die Factory-Implementierung des Socketcan-Plugins dargestellt:
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; } };
Der nächste Schritt besteht darin, eine Implementierung von QCanBusDevice bereitzustellen. Zumindest müssen die folgenden rein virtuellen Funktionen implementiert werden:
- QCanBusDevice::open()
- QCanBusDevice::close()
- QCanBusDevice::writeFrame()
- QCanBusDevice::interpretErrorFrame()
Die Methoden open() und close() werden in Verbindung mit QCanBusDevice::connectDevice() bzw. QCanBusDevice::disconnectDevice() verwendet. Lesen Sie die Funktionsdokumentation für Details zur Implementierung.
QCanBusDevice::writeFrame() ist verantwortlich für die Überprüfung der Gültigkeit von QCanBusFrame und dafür, ob das Gerät noch angeschlossen ist. Unter der Voraussetzung, dass die Prüfungen bestanden wurden, schreibt sie den Frame auf den CAN-Bus. Bei Erfolg gibt sie das Signal QCanBusDevice::framesWritten() aus, andernfalls wird QCanBusDevice::setError() mit einer entsprechenden Fehlermeldung aufgerufen. Diese Funktion kann auch verwendet werden, um einen asynchronen Schreibvorgang zu implementieren. Es liegt in der Verantwortung des Plugin-Implementierers, die entsprechenden Signale zum richtigen Zeitpunkt auszusenden.
Zu guter Letzt bietet QCanBusDevice::interpretErrorFrame eine bequeme Möglichkeit, den Inhalt eines CAN-Bus-Fehler-Frames in einen für Menschen lesbaren Fehlerstring zu übersetzen.
© 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.