Quantex GmbH
DE RU EN EL
Η περιοχή σας: Ευρώπη

Οδηγός J2534 για προγραμματιστές

Τελευταία τροποποίηση:

Τι είναι το J2534;

Το J2534 (συχνά αναφέρεται ως Pass-Thru) είναι ένα πρότυπο που αναπτύχθηκε από τη SAE (Society of Automotive Engineers) και λύνει ένα σημαντικό πρόβλημα: επιτρέπει στο ίδιο λογισμικό διάγνωσης να λειτουργεί με διαγνωστικούς προσαρμογείς από διαφορετικούς κατασκευαστές.

Η βασική ιδέα:

Φανταστείτε ότι γράφετε ένα πρόγραμμα για τη διάγνωση αυτοκινήτων. Χωρίς το πρότυπο J2534, θα έπρεπε να γράψετε μοναδικό κώδικα για κάθε προσαρμογέα (K-Line, CAN adapter κ.λπ.) που θέλετε να υποστηρίξετε. Αυτό είναι πολύπλοκο και ακριβό.

Το πρότυπο J2534 ορίζει ένα ενιαίο API (Διεπαφή Προγραμματισμού Εφαρμογών) που οι κατασκευαστές προσαρμογέων πρέπει να υλοποιούν στους οδηγούς τους. Το πρότυπο ορίζει αυτό το API μόνο ως DLL-βιβλιοθήκη για Windows.

Για τον προγραμματιστή αυτό σημαίνει:

Έτσι, το J2534 είναι μια "γέφυρα" μεταξύ της εφαρμογής σας και του διαγνωστικού προσαρμογέα, που κρύβει τις πολυπλοκότητες του συγκεκριμένου υλικού και σας επιτρέπει να επικεντρωθείτε στη λογική της διάγνωσης.

Πολλοί προγραμματιστές, εκτός των Windows, θέλουν να χρησιμοποιούν εναλλακτικές πλατφόρμες. Εκτός από την τυπική DLL για Windows, παρέχουμε επίσης βιβλιοθήκες για Linux, macOS, καθώς και τις κινητές πλατφόρμες Android και iOS.


Τι δεν κάνει το J2534 (Η δική σας ζώνη ευθύνης)

Είναι σημαντικό να κατανοήσετε ότι το J2534 είναι ένα πρότυπο για το επίπεδο μεταφοράς. Αναλαμβάνει όλη τη δουλειά αποστολής και λήψης bytes δεδομένων μέσω της επιλεγμένης φυσικής διεπαφής (CAN, K-Line κ.λπ.).

Ωστόσο, το πρότυπο J2534 δεν ορίζει:

Αυτό παραμένει έργο της εφαρμογής σας. Εσείς, ως προγραμματιστής, πρέπει να γνωρίζετε ποια συγκεκριμένα bytes πρέπει να σταλούν για να ζητήσετε, για παράδειγμα, κωδικούς σφαλμάτων ή τρέχουσες παραμέτρους, και πώς να αναλύσετε την απάντηση από τη μονάδα ελέγχου.

Για αυτό θα χρειαστείτε γνώσεις πρωτοκόλλων διάγνωσης επιπέδου εφαρμογής, όπως:

Η DLL J2534 θα παραδώσει τα bytes σας στη μονάδα ελέγχου, αλλά τι είναι αυτά τα bytes και τι να κάνετε με την απάντηση καθορίζεται από την εφαρμογή σας.


Επισκόπηση προτύπων

Το πρότυπο J2534 αποτελεί μέρος μιας μεγάλης οικογένειας προτύπων που διέπουν τη διάγνωση αυτοκινήτων. Για βαθύτερη κατανόηση, συνιστάται η ανασκόπηση των επίσημων εγγράφων.

Λεπτομερής πίνακας σχέσεων πρωτοκόλλων και προτύπων

Ο προσαρμογέας ScanDoc υλοποιεί μια μερική έκδοση του προτύπου J2534-1 και ορισμένες επεκτάσεις από το J2534-2, και επίσης διαθέτει δικές του λειτουργίες για τη διεύρυνση των δυνατοτήτων.


Υποστηριζόμενα πρωτόκολλα

Το πρότυπο J2534 ορίζει ένα σύνολο πρωτοκόλλων φυσικού και μεταφορικού επιπέδου μέσω των οποίων γίνεται η ανταλλαγή δεδομένων με τη μονάδα ελέγχου (ECU) του οχήματος. Παρακάτω περιγράφεται κάθε πρωτόκολλο που υποστηρίζεται από τον προσαρμογέα ScanDoc.

ISO 15765 (CAN με επίπεδο μεταφοράς)

Το κύριο πρωτόκολλο για τη διάγνωση σύγχρονων οχημάτων. Το ISO 15765 (επίσης γνωστό ως ISO-TP) υλοποιεί ένα επίπεδο μεταφοράς πάνω από το δίαυλο CAN: εκτελεί αυτόματα την κατάτμηση μεγάλων μηνυμάτων σε πλαίσια CAN, τη διαχείριση ροής (Flow Control) και τη συναρμολόγηση απαντήσεων από πολλαπλά πλαίσια.

Αυτό είναι το πρωτόκολλο που χρησιμοποιείται για διάγνωση μέσω UDS (ISO 14229) και OBD-II στο δίαυλο CAN. Εάν η εργασία σας είναι να στέλνετε διαγνωστικά αιτήματα και να λαμβάνετε απαντήσεις από τη μονάδα ελέγχου, χρησιμοποιήστε ISO15765.

// Σύνδεση μέσω ISO 15765 στα 500 kbit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);

CAN (ακατέργαστη ροή)

Το πρωτόκολλο CAN παρέχει πρόσβαση στην ακατέργαστη ροή πλαισίων CAN χωρίς επίπεδο μεταφοράς. Κάθε μήνυμα είναι ένα μεμονωμένο πλαίσιο CAN (έως 8 bytes δεδομένων). Ο προσαρμογέας δεν εκτελεί κατάτμηση ή συναρμολόγηση — λαμβάνετε και στέλνετε πλαίσια ως έχουν.

Χρησιμοποιήστε αυτό το πρωτόκολλο όταν χρειάζεται να εργαστείτε απευθείας με τον δίαυλο CAN: παρακολούθηση κίνησης, αποστολή μεμονωμένων πλαισίων, εργασία με μη τυπικά πρωτόκολλα πάνω από CAN.

// Σύνδεση CAN στα 500 kbit/s με 29-bit IDs
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);

ISO 14230 (KWP2000)

Ένα πρωτόκολλο διάγνωσης μέσω K-line, ευρέως χρησιμοποιούμενο σε οχήματα της δεκαετίας του 2000 (ιδιαίτερα ευρωπαϊκά). Υποστηρίζει δύο μεθόδους αρχικοποίησης σύνδεσης: 5-baud (αργή) και γρήγορη (fast init). Μετά την αρχικοποίηση, η επικοινωνία συνεχίζεται με την ταχύτητα που συμφωνήθηκε με τη μονάδα ελέγχου.

Χρησιμοποιείται για διάγνωση σε επίπεδο αντιπροσωπείας μέσω KWP2000 και για OBD-II στη γραμμή K-line.

// Σύνδεση μέσω ISO 14230 στα 10400 baud, μόνο K-line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);

ISO 9141

Ένα παλαιότερο πρωτόκολλο K-line, ορισμένο από το πρότυπο ISO 9141-2. Χρησιμοποιείται για διάγνωση OBD-II σε παλαιότερα οχήματα (πριν από το 2004-2008 ανάλογα με την περιοχή). Υποστηρίζει μόνο αρχικοποίηση 5-baud.

// Σύνδεση μέσω ISO 9141 στα 10400 baud
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);

SAE J1850 VPW

Ένα πρωτόκολλο με διαμόρφωση μεταβλητού πλάτους παλμού (Variable Pulse Width), που χρησιμοποιούνταν σε οχήματα General Motors για διάγνωση OBD-II. Λειτουργεί στα 10,4 kbit/s μέσω ενός μόνο καλωδίου.

// Σύνδεση μέσω J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);

SAE J1850 PWM

Ένα πρωτόκολλο με διαμόρφωση πλάτους παλμού (Pulse Width Modulation), που χρησιμοποιούνταν σε οχήματα Ford για διάγνωση OBD-II. Λειτουργεί στα 41,6 kbit/s μέσω δύο καλωδίων.

// Σύνδεση μέσω J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);

Πώς να ξεκινήσετε (Οδηγός βήμα προς βήμα)

Η εργασία με έναν προσαρμογέα J2534 από την εφαρμογή σας ακολουθεί συνήθως αυτόν τον αλγόριθμο:

Βήμα 1: Εύρεση και φόρτωση της J2534 DLL

Κάθε κατασκευαστής προσαρμογέα J2534 παρέχει τη δική του υλοποίηση του API ως αρχείο DLL. Κατά την εγκατάσταση του οδηγού, οι πληροφορίες για αυτή τη DLL (διαδρομή αρχείου) εγγράφονται στο μητρώο των Windows.

Η εφαρμογή σας πρέπει να:

  1. Βρει τις διαθέσιμες συσκευές J2534 στο μητρώο του συστήματος.
  2. Δώσει στον χρήστη τη δυνατότητα επιλογής του προσαρμογέα που θα χρησιμοποιηθεί (αν υπάρχουν πολλοί).
  3. Φορτώσει την αντίστοιχη DLL στη μνήμη χρησιμοποιώντας τη συνάρτηση LoadLibrary (στα Windows).

Βήμα 2: Κύριος κύκλος εργασίας με τον προσαρμογέα

Μετά τη φόρτωση της DLL και τη λήψη δεικτών συναρτήσεων, μια τυπική συνεδρία διάγνωσης μοιάζει ως εξής:

  1. Άνοιγμα σύνδεσης με τον προσαρμογέα:
    Καλέστε τη συνάρτηση PassThruOpen() για να αρχικοποιήσετε την επικοινωνία με τη φυσική συσκευή. Ως απάντηση θα λάβετε ένα DeviceID — ένα μοναδικό αναγνωριστικό για αυτή τη συνεδρία.
    // Παράδειγμα
    unsigned long deviceID;
    long result = PassThruOpen(NULL, &deviceID);
  2. Δημιουργία καναλιού επικοινωνίας με τη μονάδα ελέγχου:
    Καλέστε PassThruConnect() για να δημιουργήσετε ένα λογικό κανάλι επικοινωνίας με το όχημα μέσω συγκεκριμένου πρωτοκόλλου (π.χ. ISO15765 για τον δίαυλο CAN). Καθορίζετε το πρωτόκολλο, την ταχύτητα και άλλες παραμέτρους. Ως απάντηση λαμβάνετε ένα ChannelID.
    // Παράδειγμα
    unsigned long channelID;
    result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
  3. Ρύθμιση φίλτρων:
    Η ρύθμιση φίλτρων είναι υποχρεωτικό βήμα. Από προεπιλογή, ο προσαρμογέας δεν θα λαμβάνει εισερχόμενα μηνύματα μέχρι να ρυθμιστεί τουλάχιστον ένα φίλτρο. Τα φίλτρα σας επιτρέπουν να αποκλείσετε όλη την περιττή κίνηση στον δίαυλο και να λαμβάνετε μόνο τα δεδομένα που σας ενδιαφέρουν (π.χ. απαντήσεις από συγκεκριμένη μονάδα ελέγχου). Η συνάρτηση PassThruStartMsgFilter() χρησιμοποιείται για τη δημιουργία και ρύθμιση φίλτρων.
  4. Ανταλλαγή δεδομένων:

    Η διαδικασία ανταλλαγής δεδομένων είναι ασύγχρονη και βασίζεται σε ουρές:

    • Αποστολή δεδομένων: Η κλήση PassThruWriteMsg() δεν στέλνει το μήνυμα στον δίαυλο αμέσως. Αντ' αυτού, τοποθετεί ένα ή περισσότερα μηνύματα στην ουρά αποστολής και επιστρέφει αμέσως τον έλεγχο. Ο οδηγός του προσαρμογέα θα στείλει αυτόνομα αυτά τα μηνύματα από την ουρά μόλις αυτό καταστεί δυνατό.
    • Ανάγνωση δεδομένων: Τα μηνύματα που έρχονται από τον δίαυλο (π.χ. απαντήσεις από τη μονάδα ελέγχου) συσσωρεύονται σε μια εσωτερική ουρά λήψης. Η συνάρτηση PassThruReadMsg() χρησιμοποιείται για την ανάκτηση μηνυμάτων από αυτή την ουρά.

    Σημαντική σημείωση: Η βιβλιοθήκη J2534 είναι μονονηματική. Αυτό σημαίνει ότι όλες οι κλήσεις συναρτήσεων (PassThruWriteMsg, PassThruReadMsg κ.λπ.) για ένα κανάλι πρέπει να εκτελούνται αυστηρά διαδοχικά. Δεν μπορείτε να καλέσετε μια συνάρτηση ενώ η προηγούμενη εκτελείται ακόμη. Η απόπειρα ταυτόχρονης κλήσης συναρτήσεων από διαφορετικά νήματα για το ίδιο κανάλι θα οδηγήσει σε απρόβλεπτη συμπεριφορά.

  5. Κλείσιμο καναλιού επικοινωνίας:
    Μετά την ολοκλήρωση της εργασίας με τη μονάδα ελέγχου, κλείστε το κανάλι με PassThruDisconnect().
    // Παράδειγμα
    result = PassThruDisconnect(channelID);
  6. Κλείσιμο σύνδεσης με τον προσαρμογέα:
    Στο τέλος, όταν η εργασία με τον προσαρμογέα έχει ολοκληρωθεί πλήρως, καλέστε PassThruClose() για να απελευθερώσετε τη συσκευή.
    // Παράδειγμα
    result = PassThruClose(deviceID);

Αυτός ο κύκλος αποτελεί τη βάση κάθε εφαρμογής J2534. Στις επόμενες ενότητες περιγράφεται λεπτομερώς κάθε συνάρτηση του API και οι παράμετροί της.


Διαχείριση σφαλμάτων

Κάθε συνάρτηση του API J2534 επιστρέφει έναν κωδικό κατάστασης. Η επιτυχής εκτέλεση επιστρέφει πάντα STATUS_NOERROR (τιμή 0). Οποιαδήποτε άλλη τιμή υποδεικνύει συγκεκριμένο σφάλμα (π.χ. ERR_TIMEOUT, ERR_INVALID_CHANNEL_ID κ.λπ.).

Είναι εξαιρετικά σημαντικό να ελέγχετε την τιμή επιστροφής μετά από κάθε κλήση συνάρτησης.

Ένας ειδικός κωδικός σφάλματος είναι ο ERR_FAILED. Πρόκειται για ένα γενικό, μη ειδικό σφάλμα. Μόνο σε αυτή την περίπτωση πρέπει να καλέσετε τη συνάρτηση PassThruGetLastError() για να λάβετε από τον οδηγό μια πιο λεπτομερή, κειμενική περιγραφή του προβλήματος.

// Παράδειγμα σωστής διαχείρισης σφαλμάτων
long result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
if (result != STATUS_NOERROR)
{
    printf("Σφάλμα PassThruConnect. Κωδικός: %ld\n", result);

    // Αν το σφάλμα είναι γενικό, ζητάμε λεπτομέρειες
    if (result == ERR_FAILED)
    {
        char errorDescription[80];
        PassThruGetLastError(&errorDescription[0], 80);
        printf("  Πρόσθετες πληροφορίες: %s\n", errorDescription);
    }

    // Εδώ μπορεί να υπάρχει λογική διαχείρισης άλλων κωδικών σφαλμάτων
    // switch (result) { case ERR_TIMEOUT: ... }

    return; // Διακοπή εκτέλεσης
}

Αναφορά τυπικών συναρτήσεων J2534

Μια λεπτομερής περιγραφή κάθε συνάρτησης του προτύπου J2534 είναι διαθέσιμη στην αναφορά συναρτήσεων.