Τελευταία τροποποίηση:
Το J2534 (συχνά αναφέρεται ως Pass-Thru) είναι ένα πρότυπο που αναπτύχθηκε από τη SAE (Society of Automotive Engineers) και λύνει ένα σημαντικό πρόβλημα: επιτρέπει στο ίδιο λογισμικό διάγνωσης να λειτουργεί με διαγνωστικούς προσαρμογείς από διαφορετικούς κατασκευαστές.
Η βασική ιδέα:
Φανταστείτε ότι γράφετε ένα πρόγραμμα για τη διάγνωση αυτοκινήτων. Χωρίς το πρότυπο J2534, θα έπρεπε να γράψετε μοναδικό κώδικα για κάθε προσαρμογέα (K-Line, CAN adapter κ.λπ.) που θέλετε να υποστηρίξετε. Αυτό είναι πολύπλοκο και ακριβό.
Το πρότυπο J2534 ορίζει ένα ενιαίο API (Διεπαφή Προγραμματισμού Εφαρμογών) που οι κατασκευαστές προσαρμογέων πρέπει να υλοποιούν στους οδηγούς τους. Το πρότυπο ορίζει αυτό το API μόνο ως DLL-βιβλιοθήκη για Windows.
Για τον προγραμματιστή αυτό σημαίνει:
PassThruOpen, PassThruReadMsg).Έτσι, το J2534 είναι μια "γέφυρα" μεταξύ της εφαρμογής σας και του διαγνωστικού προσαρμογέα, που κρύβει τις πολυπλοκότητες του συγκεκριμένου υλικού και σας επιτρέπει να επικεντρωθείτε στη λογική της διάγνωσης.
Πολλοί προγραμματιστές, εκτός των Windows, θέλουν να χρησιμοποιούν εναλλακτικές πλατφόρμες. Εκτός από την τυπική DLL για Windows, παρέχουμε επίσης βιβλιοθήκες για Linux, macOS, καθώς και τις κινητές πλατφόρμες Android και iOS.
Είναι σημαντικό να κατανοήσετε ότι το J2534 είναι ένα πρότυπο για το επίπεδο μεταφοράς. Αναλαμβάνει όλη τη δουλειά αποστολής και λήψης bytes δεδομένων μέσω της επιλεγμένης φυσικής διεπαφής (CAN, K-Line κ.λπ.).
Ωστόσο, το πρότυπο J2534 δεν ορίζει:
Αυτό παραμένει έργο της εφαρμογής σας. Εσείς, ως προγραμματιστής, πρέπει να γνωρίζετε ποια συγκεκριμένα bytes πρέπει να σταλούν για να ζητήσετε, για παράδειγμα, κωδικούς σφαλμάτων ή τρέχουσες παραμέτρους, και πώς να αναλύσετε την απάντηση από τη μονάδα ελέγχου.
Για αυτό θα χρειαστείτε γνώσεις πρωτοκόλλων διάγνωσης επιπέδου εφαρμογής, όπως:
Η DLL J2534 θα παραδώσει τα bytes σας στη μονάδα ελέγχου, αλλά τι είναι αυτά τα bytes και τι να κάνετε με την απάντηση καθορίζεται από την εφαρμογή σας.
Το πρότυπο J2534 αποτελεί μέρος μιας μεγάλης οικογένειας προτύπων που διέπουν τη διάγνωση αυτοκινήτων. Για βαθύτερη κατανόηση, συνιστάται η ανασκόπηση των επίσημων εγγράφων.
Λεπτομερής πίνακας σχέσεων πρωτοκόλλων και προτύπων
Ο προσαρμογέας ScanDoc υλοποιεί μια μερική έκδοση του προτύπου J2534-1 και ορισμένες επεκτάσεις από το J2534-2, και επίσης διαθέτει δικές του λειτουργίες για τη διεύρυνση των δυνατοτήτων.
Το πρότυπο J2534 ορίζει ένα σύνολο πρωτοκόλλων φυσικού και μεταφορικού επιπέδου μέσω των οποίων γίνεται η ανταλλαγή δεδομένων με τη μονάδα ελέγχου (ECU) του οχήματος. Παρακάτω περιγράφεται κάθε πρωτόκολλο που υποστηρίζεται από τον προσαρμογέα ScanDoc.
Το κύριο πρωτόκολλο για τη διάγνωση σύγχρονων οχημάτων. Το ISO 15765 (επίσης γνωστό ως ISO-TP) υλοποιεί ένα επίπεδο μεταφοράς πάνω από το δίαυλο CAN: εκτελεί αυτόματα την κατάτμηση μεγάλων μηνυμάτων σε πλαίσια CAN, τη διαχείριση ροής (Flow Control) και τη συναρμολόγηση απαντήσεων από πολλαπλά πλαίσια.
Αυτό είναι το πρωτόκολλο που χρησιμοποιείται για διάγνωση μέσω UDS (ISO 14229) και OBD-II στο δίαυλο CAN. Εάν η εργασία σας είναι να στέλνετε διαγνωστικά αιτήματα και να λαμβάνετε απαντήσεις από τη μονάδα ελέγχου, χρησιμοποιήστε ISO15765.
CAN_29BIT_IDFLOW_CONTROL_FILTER (έως 16 ανά κανάλι)ISO15765_ADDR_TYPE// Σύνδεση μέσω ISO 15765 στα 500 kbit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
Το πρωτόκολλο CAN παρέχει πρόσβαση στην ακατέργαστη ροή πλαισίων CAN χωρίς επίπεδο μεταφοράς. Κάθε μήνυμα είναι ένα μεμονωμένο πλαίσιο CAN (έως 8 bytes δεδομένων). Ο προσαρμογέας δεν εκτελεί κατάτμηση ή συναρμολόγηση — λαμβάνετε και στέλνετε πλαίσια ως έχουν.
Χρησιμοποιήστε αυτό το πρωτόκολλο όταν χρειάζεται να εργαστείτε απευθείας με τον δίαυλο CAN: παρακολούθηση κίνησης, αποστολή μεμονωμένων πλαισίων, εργασία με μη τυπικά πρωτόκολλα πάνω από CAN.
CAN_29BIT_IDPASS_FILTER και BLOCK_FILTER (έως 10 από κάθε τύπο)// Σύνδεση CAN στα 500 kbit/s με 29-bit IDs
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);
Ένα πρωτόκολλο διάγνωσης μέσω K-line, ευρέως χρησιμοποιούμενο σε οχήματα της δεκαετίας του 2000 (ιδιαίτερα ευρωπαϊκά). Υποστηρίζει δύο μεθόδους αρχικοποίησης σύνδεσης: 5-baud (αργή) και γρήγορη (fast init). Μετά την αρχικοποίηση, η επικοινωνία συνεχίζεται με την ταχύτητα που συμφωνήθηκε με τη μονάδα ελέγχου.
Χρησιμοποιείται για διάγνωση σε επίπεδο αντιπροσωπείας μέσω KWP2000 και για OBD-II στη γραμμή K-line.
FIVE_BAUD_INIT) ή γρήγορη (FAST_INIT) μέσω PassThruIoctlISO9141_K_LINE: εάν οριστεί, η αρχικοποίηση γίνεται μόνο μέσω K-line (χωρίς L-line)SET_CONFIG// Σύνδεση μέσω ISO 14230 στα 10400 baud, μόνο K-line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);
Ένα παλαιότερο πρωτόκολλο K-line, ορισμένο από το πρότυπο ISO 9141-2. Χρησιμοποιείται για διάγνωση OBD-II σε παλαιότερα οχήματα (πριν από το 2004-2008 ανάλογα με την περιοχή). Υποστηρίζει μόνο αρχικοποίηση 5-baud.
FIVE_BAUD_INIT// Σύνδεση μέσω ISO 9141 στα 10400 baud
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);
Ένα πρωτόκολλο με διαμόρφωση μεταβλητού πλάτους παλμού (Variable Pulse Width), που χρησιμοποιούνταν σε οχήματα General Motors για διάγνωση OBD-II. Λειτουργεί στα 10,4 kbit/s μέσω ενός μόνο καλωδίου.
// Σύνδεση μέσω J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);
Ένα πρωτόκολλο με διαμόρφωση πλάτους παλμού (Pulse Width Modulation), που χρησιμοποιούνταν σε οχήματα Ford για διάγνωση OBD-II. Λειτουργεί στα 41,6 kbit/s μέσω δύο καλωδίων.
// Σύνδεση μέσω J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);
Η εργασία με έναν προσαρμογέα J2534 από την εφαρμογή σας ακολουθεί συνήθως αυτόν τον αλγόριθμο:
Κάθε κατασκευαστής προσαρμογέα J2534 παρέχει τη δική του υλοποίηση του API ως αρχείο DLL. Κατά την εγκατάσταση του οδηγού, οι πληροφορίες για αυτή τη DLL (διαδρομή αρχείου) εγγράφονται στο μητρώο των Windows.
Η εφαρμογή σας πρέπει να:
LoadLibrary (στα Windows).Μετά τη φόρτωση της DLL και τη λήψη δεικτών συναρτήσεων, μια τυπική συνεδρία διάγνωσης μοιάζει ως εξής:
PassThruOpen() για να αρχικοποιήσετε την επικοινωνία με τη φυσική συσκευή. Ως απάντηση θα λάβετε ένα DeviceID — ένα μοναδικό αναγνωριστικό για αυτή τη συνεδρία.
// Παράδειγμα
unsigned long deviceID;
long result = PassThruOpen(NULL, &deviceID);
PassThruConnect() για να δημιουργήσετε ένα λογικό κανάλι επικοινωνίας με το όχημα μέσω συγκεκριμένου πρωτοκόλλου (π.χ. ISO15765 για τον δίαυλο CAN). Καθορίζετε
το πρωτόκολλο, την ταχύτητα και άλλες παραμέτρους. Ως απάντηση λαμβάνετε ένα ChannelID.
// Παράδειγμα
unsigned long channelID;
result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
PassThruStartMsgFilter() χρησιμοποιείται για τη δημιουργία και ρύθμιση φίλτρων.
Η διαδικασία ανταλλαγής δεδομένων είναι ασύγχρονη και βασίζεται σε ουρές:
PassThruWriteMsg() δεν στέλνει το μήνυμα στον δίαυλο αμέσως. Αντ' αυτού, τοποθετεί ένα ή περισσότερα μηνύματα στην ουρά αποστολής και επιστρέφει αμέσως τον έλεγχο.
Ο οδηγός του προσαρμογέα θα στείλει αυτόνομα αυτά τα μηνύματα από την ουρά μόλις αυτό καταστεί δυνατό.PassThruReadMsg() χρησιμοποιείται για την ανάκτηση μηνυμάτων από αυτή την ουρά.Σημαντική σημείωση: Η βιβλιοθήκη J2534 είναι μονονηματική. Αυτό σημαίνει ότι όλες οι κλήσεις συναρτήσεων (PassThruWriteMsg, PassThruReadMsg κ.λπ.) για ένα κανάλι πρέπει να εκτελούνται αυστηρά διαδοχικά.
Δεν μπορείτε να καλέσετε μια συνάρτηση ενώ η προηγούμενη εκτελείται ακόμη. Η απόπειρα ταυτόχρονης κλήσης συναρτήσεων από διαφορετικά νήματα για το ίδιο κανάλι θα οδηγήσει σε απρόβλεπτη συμπεριφορά.
PassThruDisconnect().
// Παράδειγμα
result = PassThruDisconnect(channelID);
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 είναι διαθέσιμη στην αναφορά συναρτήσεων.