Quantex GmbH
Votre région : Europe

Guide de J2534 pour les développeurs

Dernière modification :

Qu'est-ce que J2534 ?

J2534 (souvent appelé Pass-Thru) est un standard développé par la SAE (Society of Automotive Engineers) qui résout un problème important : il permet à un même logiciel de diagnostic de fonctionner avec des adaptateurs de diagnostic de différents fabricants.

Idée principale :

Imaginez que vous écrivez un programme pour le diagnostic automobile. Sans le standard J2534, vous devriez écrire un code distinct pour chaque adaptateur (K-Line, adaptateur CAN, etc.) que vous souhaitez prendre en charge. C'est compliqué et coûteux.

Le standard J2534 définit une API (interface de programmation) uniforme que les fabricants d'adaptateurs doivent implémenter dans leurs pilotes. Le standard définit cette API uniquement sous la forme d'une bibliothèque DLL pour Windows

Pour le développeur, cela signifie :

Ainsi, J2534 est un « pont » entre votre application et l'adaptateur de diagnostic qui masque la complexité du matériel concret et permet de se concentrer sur la logique du diagnostic.

De nombreux développeurs, outre Windows, souhaitent utiliser des plateformes alternatives. Outre la bibliothèque DLL standard pour Windows, nous proposons également des bibliothèques pour Linux, macOS, ainsi que pour les plateformes mobiles Android et iOS.


Ce que J2534 ne fait pas (Votre domaine de responsabilité)

Il est important de comprendre que J2534 est un standard de la couche de transport. Il prend en charge tout le travail d'envoi et de réception des octets de données via l'interface physique choisie (CAN, K-Line, etc.).

Cependant, le standard J2534 ne définit pas :

Cela reste la tâche de votre application. En tant que développeur, vous devez savoir exactement quels octets envoyer pour demander, par exemple, les codes d'erreur ou les paramètres actuels, et comment analyser la réponse de l'unité de commande.

Pour cela, vous aurez besoin de connaître les protocoles de diagnostic applicatifs, tels que :

La DLL J2534 acheminera vos octets jusqu'à l'ECU, mais quels octets sont concernés et que faire de la réponse, c'est votre programme qui le décide.


Aperçu des standards

Le standard J2534 fait partie d'une grande famille de standards qui régissent le diagnostic automobile. Pour une compréhension approfondie, il est recommandé de consulter les documents officiels.

Tableau détaillé de la correspondance entre protocoles et standards

L'adaptateur ScanDoc implémente une version non complète du standard J2534-1 et certaines extensions de J2534-2, et dispose en outre de ses propres fonctions pour étendre les possibilités.


Protocoles pris en charge

Le standard J2534 définit un ensemble de protocoles de la couche physique et de transport via lesquels s'effectue l'échange de données avec l'ECU du véhicule. Chaque protocole pris en charge par l'adaptateur ScanDoc est décrit ci-dessous.

ISO 15765 (CAN avec couche de transport)

Protocole principal pour le diagnostic des automobiles modernes. ISO 15765 (également connu sous le nom d'ISO-TP) implémente la couche de transport au-dessus du bus CAN : il effectue automatiquement la segmentation des messages longs en trames CAN, le contrôle de flux (Flow Control) et l'assemblage de la réponse à partir de plusieurs trames.

C'est précisément ce protocole qui est utilisé pour le diagnostic via UDS (ISO 14229) et OBD-II sur le bus CAN. Si votre tâche consiste à envoyer des requêtes de diagnostic et à recevoir des réponses de l'ECU, utilisez ISO15765.

// Connexion via ISO 15765 à 500 kbit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);

CAN (flux brut)

Le protocole CAN fournit un accès au flux brut de trames CAN sans couche de transport. Chaque message est une seule trame CAN (jusqu'à 8 octets de données). L'adaptateur n'effectue ni la segmentation ni l'assemblage — vous recevez et envoyez les trames telles quelles.

Utilisez ce protocole lorsque vous devez travailler directement avec le bus CAN : surveillance du trafic, envoi de trames individuelles, travail avec des protocoles non standard au-dessus de CAN.

// Connexion CAN à 500 kbit/s avec des ID de 29 bits
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);

ISO 14230 (KWP2000)

Protocole de diagnostic par K-Line, largement utilisé dans les automobiles des années 2000 (en particulier européennes). Il prend en charge deux modes d'initialisation de la connexion : à 5 bauds (lent) et rapide (fast init). Après l'initialisation, l'échange s'effectue au débit convenu avec l'ECU.

Il est utilisé pour le diagnostic en concession via KWP2000 et pour OBD-II par K-Line.

// Connexion via ISO 14230 à 10400 bauds, uniquement K-Line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);

ISO 9141

Protocole de K-Line antérieur, défini par le standard ISO 9141-2. Il est utilisé pour le diagnostic OBD-II dans les automobiles plus anciennes (jusqu'à 2004-2008 selon la région). Il ne prend en charge que l'initialisation à 5 bauds.

// Connexion via ISO 9141 à 10400 bauds
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);

SAE J1850 VPW

Protocole avec modulation de largeur d'impulsion variable (Variable Pulse Width), utilisé dans les automobiles de General Motors pour le diagnostic OBD-II. Il fonctionne à un débit de 10,4 kbit/s sur un seul fil.

// Connexion via J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);

SAE J1850 PWM

Protocole avec modulation de largeur d'impulsion (Pulse Width Modulation), utilisé dans les automobiles de Ford pour le diagnostic OBD-II. Il fonctionne à un débit de 41,6 kbit/s sur deux fils.

// Connexion via J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);

Comment démarrer (Guide étape par étape)

Le travail avec un adaptateur J2534 depuis votre application suit généralement cet algorithme :

Étape 1 : Recherche et chargement de la DLL J2534

Chaque fabricant d'adaptateurs J2534 fournit son implémentation de l'API sous la forme d'un fichier DLL. Lors de l'installation du pilote, les informations sur cette DLL (le chemin du fichier) sont inscrites dans le registre de Windows.

Votre application doit :

  1. Trouver les périphériques J2534 disponibles dans le registre du système.
  2. Proposer à l'utilisateur de choisir quel adaptateur utiliser (s'il y en a plusieurs).
  3. Charger la DLL correspondante en mémoire à l'aide de la fonction LoadLibrary (sous Windows).

Étape 2 : Boucle principale de travail avec l'adaptateur

Après le chargement de la DLL et l'obtention des pointeurs vers les fonctions, une session de diagnostic typique se présente ainsi :

  1. Ouvrir la connexion avec l'adaptateur :
    Appelez la fonction PassThruOpen() pour initialiser la communication avec le périphérique physique. En réponse, vous obtiendrez un DeviceID — un identifiant unique de cette session.
    // Exemple
    unsigned long deviceID;
    long result = PassThruOpen(NULL, &deviceID);
  2. Établir le canal de communication avec l'ECU :
    Appelez PassThruConnect() pour établir un canal logique de communication avec le véhicule via un protocole déterminé (par exemple, ISO15765 pour le bus CAN). Vous indiquez le protocole, le débit et d'autres paramètres. En réponse, vous obtenez un ChannelID.
    // Exemple
    unsigned long channelID;
    result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
  3. Définir les filtres :
    La configuration des filtres est une étape obligatoire. Par défaut, l'adaptateur n'acceptera pas les messages entrants tant qu'au moins un filtre n'est pas configuré. Les filtres permettent d'écarter tout le trafic inutile du bus et de ne recevoir que les données qui vous intéressent (par exemple, les réponses d'une ECU concrète). Pour créer et configurer les filtres, on utilise la fonction PassThruStartMsgFilter().
  4. Échange de données :

    Le processus d'échange de données est asynchrone et repose sur des files d'attente :

    • Envoi de données : L'appel de la fonction PassThruWriteMsg() n'envoie pas le message au bus immédiatement. À la place, il place un ou plusieurs messages dans la file d'attente d'envoi et rend aussitôt le contrôle. Le pilote de l'adaptateur enverra de lui-même ces messages de la file d'attente dès que la possibilité se présentera.
    • Lecture de données : Les messages qui arrivent du bus (par exemple, les réponses de l'ECU) s'accumulent dans une file d'attente interne de réception. La fonction PassThruReadMsg() est utilisée pour extraire les messages de cette file d'attente.

    Remarque importante : La bibliothèque J2534 est monothread. Cela signifie que tous les appels aux fonctions (PassThruWriteMsg, PassThruReadMsg, etc.) pour un même canal doivent s'exécuter de manière strictement séquentielle. On ne peut pas appeler une fonction tant que l'exécution de la précédente n'est pas terminée. La tentative d'appeler simultanément des fonctions depuis différents threads pour un même canal provoquera un comportement imprévisible.

  5. Fermer le canal de communication :
    Après avoir terminé le travail avec l'ECU, fermez le canal à l'aide de PassThruDisconnect().
    // Exemple
    result = PassThruDisconnect(channelID);
  6. Fermer la connexion avec l'adaptateur :
    Tout à la fin, lorsque le travail avec l'adaptateur est complètement terminé, appelez PassThruClose() pour libérer le périphérique.
    // Exemple
    result = PassThruClose(deviceID);

Cette boucle est la base de toute application J2534. Les sections suivantes décrivent en détail chaque fonction de l'API et ses paramètres.


Gestion des erreurs

Chaque fonction de l'API J2534 renvoie un code d'état. Une exécution réussie renvoie toujours STATUS_NOERROR (valeur 0). Toute autre valeur indique une erreur concrète (par exemple, ERR_TIMEOUT, ERR_INVALID_CHANNEL_ID etc.).

Il est extrêmement important de vérifier la valeur renvoyée après chaque appel de fonction.

Un code d'erreur particulier est ERR_FAILED. Il s'agit d'une erreur générale et non spécifique. Uniquement dans ce cas, il faut appeler la fonction PassThruGetLastError() pour obtenir du pilote une description textuelle plus détaillée du problème.

// Exemple de gestion correcte des erreurs
long result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
if (result != STATUS_NOERROR)
{
    printf("Erreur de PassThruConnect. Code : %ld\n", result);

    // Si l'erreur est générale, nous demandons les détails
    if (result == ERR_FAILED)
    {
        char errorDescription[80];
        PassThruGetLastError(&errorDescription[0], 80);
        printf("  Informations supplémentaires : %s\n", errorDescription);
    }

    // Ici peut figurer la logique de gestion des autres codes d'erreur
    // switch (result) { case ERR_TIMEOUT: ... }

    return; // Nous interrompons l'exécution
}

Référence des fonctions standard de J2534

La description détaillée de chaque fonction du standard J2534 a été déplacée dans la référence des fonctions.