Quantex GmbH
DE RU EN EL
Ihre Region: Europa

J2534-Entwicklerhandbuch

Letzte Änderung:

Was ist J2534?

J2534 (oft als Pass-Thru bezeichnet) ist ein von der SAE (Society of Automotive Engineers) entwickelter Standard, der eine wichtige Aufgabe löst: Er ermöglicht es, dass dieselbe Diagnosesoftware mit Diagnoseadaptern verschiedener Hersteller funktioniert.

Die Grundidee:

Stellen Sie sich vor, Sie schreiben ein Programm zur Fahrzeugdiagnose. Ohne den J2534-Standard müssten Sie für jeden Adapter (K-Line, CAN-Adapter usw.), den Sie unterstützen möchten, einen eigenen Code schreiben. Das ist aufwendig und teuer.

Der J2534-Standard definiert eine einheitliche API (Programmierschnittstelle), die Adapterhersteller in ihren Treibern implementieren müssen. Der Standard definiert diese API ausschließlich als DLL-Bibliothek für Windows.

Für Sie als Entwickler bedeutet das:

Somit ist J2534 eine "Brücke" zwischen Ihrer Anwendung und dem Diagnoseadapter, die die Komplexität der spezifischen Hardware verbirgt und es Ihnen ermöglicht, sich auf die Diagnoselogik zu konzentrieren.

Viele Entwickler möchten neben Windows auch alternative Plattformen nutzen. Wir bieten neben der Standard-DLL für Windows auch Bibliotheken für Linux, macOS sowie die mobilen Plattformen Android und iOS an.


Was J2534 nicht leistet (Ihr Verantwortungsbereich)

Es ist wichtig zu verstehen, dass J2534 ein Standard für die Transportschicht ist. Er übernimmt die gesamte Arbeit des Sendens und Empfangens von Datenbytes über die gewählte physische Schnittstelle (CAN, K-Line usw.).

Der J2534-Standard definiert jedoch nicht:

Dies bleibt die Aufgabe Ihrer Anwendung. Sie als Entwickler müssen wissen, welche konkreten Bytes gesendet werden müssen, um beispielsweise Fehlercodes oder aktuelle Parameter abzufragen, und wie die Antwort des Steuergeräts zu interpretieren ist.

Dafür benötigen Sie Kenntnisse der anwendungsbezogenen Diagnoseprotokolle, wie z.B.:

Die J2534-DLL liefert Ihre Bytes an das Steuergerät, aber was diese Bytes bedeuten und was mit der Antwort geschehen soll, bestimmt Ihre Anwendung.


Überblick über die Standards

Der J2534-Standard ist Teil einer großen Familie von Standards, die die Fahrzeugdiagnose regeln. Für ein tieferes Verständnis empfehlen wir, die offiziellen Dokumente einzusehen.

Detaillierte Tabelle der Protokoll- und Standardzuordnungen

Der ScanDoc-Adapter implementiert eine Teilversion des J2534-1-Standards und einige Erweiterungen aus J2534-2 und verfügt darüber hinaus über eigene Funktionen zur Erweiterung der Möglichkeiten.


Unterstützte Protokolle

Der J2534-Standard definiert eine Reihe von Protokollen auf physischer und Transportebene, über die der Datenaustausch mit dem Fahrzeug-Steuergerät erfolgt. Im Folgenden wird jedes vom ScanDoc-Adapter unterstützte Protokoll beschrieben.

ISO 15765 (CAN mit Transportschicht)

Das primäre Protokoll für die Diagnose moderner Fahrzeuge. ISO 15765 (auch bekannt als ISO-TP) implementiert eine Transportschicht über dem CAN-Bus: Es führt automatisch die Segmentierung langer Nachrichten in CAN-Frames, die Flusssteuerung (Flow Control) und den Zusammenbau von Antworten aus mehreren Frames durch.

Dieses Protokoll wird für die Diagnose über UDS (ISO 14229) und OBD-II auf dem CAN-Bus verwendet. Wenn Ihre Aufgabe darin besteht, Diagnoseanfragen zu senden und Antworten vom Steuergerät zu empfangen, verwenden Sie ISO15765.

// Verbindung über ISO 15765 bei 500 kBit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);

CAN (Rohdatenstrom)

Das CAN-Protokoll bietet Zugriff auf den rohen Strom von CAN-Frames ohne Transportschicht. Jede Nachricht ist ein einzelner CAN-Frame (bis zu 8 Bytes Daten). Der Adapter führt keine Segmentierung und keinen Zusammenbau durch — Sie empfangen und senden Frames unverändert.

Verwenden Sie dieses Protokoll, wenn Sie direkt mit dem CAN-Bus arbeiten müssen: Verkehrsüberwachung, Senden einzelner Frames, Arbeiten mit nicht standardisierten Protokollen über CAN.

// CAN-Verbindung bei 500 kBit/s mit 29-Bit-IDs
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);

ISO 14230 (KWP2000)

Ein K-Line-Diagnoseprotokoll, das in Fahrzeugen der 2000er Jahre (insbesondere europäischen) weit verbreitet ist. Es unterstützt zwei Methoden der Verbindungsinitialisierung: 5-Baud (langsam) und schnelle Initialisierung (Fast Init). Nach der Initialisierung erfolgt die Kommunikation mit der vom Steuergerät ausgehandelten Geschwindigkeit.

Wird für die Händlerdiagnose über KWP2000 und für OBD-II auf der K-Line verwendet.

// Verbindung über ISO 14230 bei 10400 Baud, nur K-Line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);

ISO 9141

Ein älteres K-Line-Protokoll, definiert durch den Standard ISO 9141-2. Wird für die OBD-II-Diagnose in älteren Fahrzeugen verwendet (vor 2004-2008, je nach Region). Unterstützt nur die 5-Baud-Initialisierung.

// Verbindung über ISO 9141 bei 10400 Baud
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);

SAE J1850 VPW

Ein Protokoll mit variabler Impulsbreitenmodulation (Variable Pulse Width), das in Fahrzeugen von General Motors für die OBD-II-Diagnose verwendet wurde. Arbeitet mit 10,4 kBit/s über eine einzelne Leitung.

// Verbindung über J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);

SAE J1850 PWM

Ein Protokoll mit Impulsbreitenmodulation (Pulse Width Modulation), das in Ford-Fahrzeugen für die OBD-II-Diagnose verwendet wurde. Arbeitet mit 41,6 kBit/s über zwei Leitungen.

// Verbindung über J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);

Erste Schritte (Schritt-für-Schritt-Anleitung)

Die Arbeit mit einem J2534-Adapter aus Ihrer Anwendung folgt in der Regel diesem Ablauf:

Schritt 1: J2534-DLL finden und laden

Jeder J2534-Adapterhersteller stellt seine eigene API-Implementierung als DLL-Datei bereit. Bei der Treiberinstallation werden Informationen über diese DLL (Dateipfad) in die Windows-Registrierung geschrieben.

Ihre Anwendung sollte:

  1. Verfügbare J2534-Geräte in der Systemregistrierung finden.
  2. Dem Benutzer die Auswahl des zu verwendenden Adapters ermöglichen (falls mehrere vorhanden sind).
  3. Die entsprechende DLL mit der Funktion LoadLibrary (unter Windows) in den Speicher laden.

Schritt 2: Hauptarbeitsablauf mit dem Adapter

Nach dem Laden der DLL und dem Abrufen der Funktionszeiger sieht eine typische Diagnosesitzung folgendermaßen aus:

  1. Verbindung zum Adapter öffnen:
    Rufen Sie die Funktion PassThruOpen() auf, um die Kommunikation mit dem physischen Gerät zu initialisieren. Als Antwort erhalten Sie eine DeviceID — eine eindeutige Kennung für diese Sitzung.
    // Beispiel
    unsigned long deviceID;
    long result = PassThruOpen(NULL, &deviceID);
  2. Kommunikationskanal mit dem Steuergerät herstellen:
    Rufen Sie PassThruConnect() auf, um einen logischen Kommunikationskanal mit dem Fahrzeug über ein bestimmtes Protokoll herzustellen (z.B. ISO15765 für den CAN-Bus). Sie geben das Protokoll, die Geschwindigkeit und weitere Parameter an. Als Antwort erhalten Sie eine ChannelID.
    // Beispiel
    unsigned long channelID;
    result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
  3. Filter einrichten:
    Die Einrichtung von Filtern ist ein obligatorischer Schritt. Standardmäßig empfängt der Adapter keine eingehenden Nachrichten, bis mindestens ein Filter konfiguriert wurde. Filter ermöglichen es, den gesamten unnötigen Verkehr auf dem Bus herauszufiltern und nur die für Sie relevanten Daten zu empfangen (z.B. Antworten von einem bestimmten Steuergerät). Die Funktion PassThruStartMsgFilter() wird zum Erstellen und Konfigurieren von Filtern verwendet.
  4. Datenaustausch:

    Der Datenaustausch ist asynchron und basiert auf Warteschlangen:

    • Daten senden: Der Aufruf von PassThruWriteMsg() sendet die Nachricht nicht sofort auf den Bus. Stattdessen werden eine oder mehrere Nachrichten in die Sendewarteschlange eingestellt und die Steuerung wird sofort zurückgegeben. Der Adaptertreiber sendet diese Nachrichten aus der Warteschlange selbstständig, sobald es möglich ist.
    • Daten lesen: Vom Bus eingehende Nachrichten (z.B. Antworten des Steuergeräts) sammeln sich in einer internen Empfangswarteschlange. Die Funktion PassThruReadMsg() wird zum Abrufen von Nachrichten aus dieser Warteschlange verwendet.

    Wichtiger Hinweis: Die J2534-Bibliothek ist single-threaded. Das bedeutet, dass alle Funktionsaufrufe (PassThruWriteMsg, PassThruReadMsg usw.) für einen einzelnen Kanal strikt sequenziell ausgeführt werden müssen. Sie dürfen keine Funktion aufrufen, während die vorherige noch ausgeführt wird. Der Versuch, Funktionen gleichzeitig aus verschiedenen Threads für denselben Kanal aufzurufen, führt zu unvorhersehbarem Verhalten.

  5. Kommunikationskanal schließen:
    Schließen Sie nach Abschluss der Arbeit mit dem Steuergerät den Kanal mit PassThruDisconnect().
    // Beispiel
    result = PassThruDisconnect(channelID);
  6. Verbindung zum Adapter schließen:
    Rufen Sie ganz zum Schluss, wenn die Arbeit mit dem Adapter vollständig abgeschlossen ist, PassThruClose() auf, um das Gerät freizugeben.
    // Beispiel
    result = PassThruClose(deviceID);

Dieser Ablauf ist die Grundlage jeder J2534-Anwendung. In den folgenden Abschnitten wird jede API-Funktion und ihre Parameter detailliert beschrieben.


Fehlerbehandlung

Jede J2534-API-Funktion gibt einen Statuscode zurück. Eine erfolgreiche Ausführung gibt immer STATUS_NOERROR (Wert 0) zurück. Jeder andere Wert weist auf einen spezifischen Fehler hin (z.B. ERR_TIMEOUT, ERR_INVALID_CHANNEL_ID usw.).

Es ist äußerst wichtig, den Rückgabewert nach jedem Funktionsaufruf zu überprüfen.

Ein besonderer Fehlercode ist ERR_FAILED. Dies ist ein allgemeiner, unspezifischer Fehler. Nur in diesem Fall sollten Sie die Funktion PassThruGetLastError() aufrufen, um vom Treiber eine detailliertere, textuelle Beschreibung des Problems zu erhalten.

// Beispiel für korrekte Fehlerbehandlung
long result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
if (result != STATUS_NOERROR)
{
    printf("PassThruConnect-Fehler. Code: %ld\n", result);

    // Bei allgemeinem Fehler Details anfordern
    if (result == ERR_FAILED)
    {
        char errorDescription[80];
        PassThruGetLastError(&errorDescription[0], 80);
        printf("  Zusätzliche Information: %s\n", errorDescription);
    }

    // Hier kann Logik zur Behandlung anderer Fehlercodes stehen
    // switch (result) { case ERR_TIMEOUT: ... }

    return; // Ausführung abbrechen
}

Referenz der J2534-Standardfunktionen

Eine detaillierte Beschreibung jeder Funktion des J2534-Standards finden Sie in der Funktionsreferenz.