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:

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:

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:

HerstellerPlugin (Schlüssel)Kurzbeschreibung
CAN über Linux-SockelSocketCAN (socketcan)CAN-Bus-Plugin mit Linux-Sockeln und Open-Source-Treibern.
CAN über SAE J2534 Pass-ThruPassThruCAN (passthrucan)CAN-Bus-Plugin unter Verwendung der SAE J2534 Pass-Thru-Schnittstelle.
SYS TEC elektronischSystecCAN (systeccan)CAN-Bus Backend unter Verwendung der SYS TEC CAN-Adapter.
PEAK-SystemPeakCAN (peakcan)CAN-Bus-Plugin unter Verwendung der PEAK-CAN-Adapter.
MHS ElektronikTinyCAN (tinycan)CAN-Bus-Plugin unter Verwendung der MHS-CAN-Adapter.
Vektor InformatikVectorCAN (vectorcan)CAN-Bus-Plugin unter Verwendung der Vector CAN-Adapter.
Virtuelle CAN-SchnittstelleVirtualCAN (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:

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.