Ostatnia modyfikacja:
J2534 (często nazywany Pass-Thru) to standard opracowany przez SAE (Society of Automotive Engineers), który rozwiązuje istotny problem: pozwala temu samemu oprogramowaniu diagnostycznemu współpracować z adapterami diagnostycznymi różnych producentów.
Główna idea:
Wyobraź sobie, że piszesz program do diagnostyki samochodów. Bez standardu J2534 musiałbyś napisać osobny kod dla każdego adaptera (K-Line, adapter CAN itd.), który chcesz obsługiwać. To skomplikowane i kosztowne.
Standard J2534 definiuje jednolite API (interfejs programistyczny), które producenci adapterów muszą zaimplementować w swoich sterownikach. Standard definiuje to API wyłącznie jako bibliotekę DLL dla systemu Windows
Dla programisty oznacza to:
PassThruOpen, PassThruReadMsg).W ten sposób J2534 to „most” między Twoją aplikacją a adapterem diagnostycznym, który ukrywa złożoność konkretnego sprzętu i pozwala skupić się na logice diagnostyki.
Wielu programistów, poza systemem Windows, chce korzystać z alternatywnych platform. Oprócz standardowej biblioteki DLL dla Windows oferujemy także biblioteki dla Linux, macOS, a także platform mobilnych Android i iOS.
Ważne, aby rozumieć, że J2534 to standard warstwy transportowej. Bierze na siebie całą pracę związaną z wysyłaniem i odbieraniem bajtów danych przez wybrany interfejs fizyczny (CAN, K-Line itd.).
Standard J2534 nie definiuje jednak:
To pozostaje zadaniem Twojej aplikacji. Jako programista musisz wiedzieć, jakie dokładnie bajty należy wysłać, aby zażądać na przykład kodów błędów lub bieżących parametrów, oraz jak przeanalizować odpowiedź jednostki sterującej.
Do tego potrzebna Ci będzie znajomość aplikacyjnych protokołów diagnostycznych, takich jak:
J2534 DLL dostarczy Twoje bajty do ECU, ale co to za bajty i co zrobić z odpowiedzią — decyduje Twój program.
Standard J2534 jest częścią dużej rodziny standardów regulujących diagnostykę samochodową. Dla głębokiego zrozumienia zalecane jest zapoznanie się z oficjalnymi dokumentami.
Szczegółowa tabela zależności protokołów i standardów
Adapter ScanDoc implementuje nie pełną wersję standardu J2534-1 oraz niektóre rozszerzenia z J2534-2, a także posiada własne funkcje rozszerzające możliwości.
Standard J2534 definiuje zestaw protokołów warstwy fizycznej i transportowej, za pośrednictwem których odbywa się wymiana danych z ECU pojazdu. Poniżej opisano każdy protokół obsługiwany przez adapter ScanDoc.
Główny protokół do diagnostyki nowoczesnych samochodów. ISO 15765 (znany także jako ISO-TP) realizuje warstwę transportową ponad magistralą CAN: automatycznie wykonuje segmentację długich komunikatów na ramki CAN, sterowanie przepływem (Flow Control) i składanie odpowiedzi z wielu ramek.
Właśnie ten protokół jest używany do diagnostyki przez UDS (ISO 14229) i OBD-II na magistrali CAN. Jeśli Twoim zadaniem jest wysyłanie zapytań diagnostycznych i odbieranie odpowiedzi od ECU, użyj ISO15765.
CAN_29BIT_IDFLOW_CONTROL_FILTER (do 16 na kanał)ISO15765_ADDR_TYPE// Połączenie przez ISO 15765 na 500 kbit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
Protokół CAN zapewnia dostęp do surowego strumienia ramek CAN bez warstwy transportowej. Każdy komunikat to jedna ramka CAN (do 8 bajtów danych). Adapter nie wykonuje segmentacji i składania — odbierasz i wysyłasz ramki
w niezmienionej postaci.
Użyj tego protokołu, gdy musisz pracować z magistralą CAN bezpośrednio: monitorowanie ruchu, wysyłanie pojedynczych ramek, praca z niestandardowymi protokołami ponad CAN.
CAN_29BIT_IDPASS_FILTER i BLOCK_FILTER (do 10 każdego typu)// Połączenie CAN na 500 kbit/s z 29-bitowymi ID
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);
Protokół diagnostyki przez K-Line, szeroko stosowany w samochodach z lat 2000. (zwłaszcza europejskich). Obsługuje dwa sposoby inicjalizacji połączenia: 5-bodową (wolną) i szybką (fast init). Po inicjalizacji wymiana odbywa się z prędkością uzgodnioną z ECU.
Używany do diagnostyki dealerskiej przez KWP2000 oraz do OBD-II na K-Line.
FIVE_BAUD_INIT) lub szybka (FAST_INIT) przez PassThruIoctlISO9141_K_LINE: jeśli ustawiona, inicjalizacja tylko przez K-Line (bez L-Line)SET_CONFIG// Połączenie przez ISO 14230 na 10400 bodów, tylko K-Line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);
Wcześniejszy protokół K-Line, zdefiniowany standardem ISO 9141-2. Używany do diagnostyki OBD-II w starszych samochodach (do lat 2004-2008 w zależności od regionu). Obsługuje tylko inicjalizację 5-bodową.
FIVE_BAUD_INIT// Połączenie przez ISO 9141 na 10400 bodów
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);
Protokół z modulacją zmiennej szerokości impulsu (Variable Pulse Width), stosowany w samochodach General Motors do diagnostyki OBD-II. Działa z prędkością 10,4 kbit/s po jednym przewodzie.
// Połączenie przez J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);
Protokół z modulacją szerokości impulsu (Pulse Width Modulation), stosowany w samochodach Ford do diagnostyki OBD-II. Działa z prędkością 41,6 kbit/s po dwóch przewodach.
// Połączenie przez J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);
Praca z adapterem J2534 z poziomu Twojej aplikacji zwykle przebiega według tego algorytmu:
Każdy producent adaptera J2534 udostępnia swoją implementację API w postaci pliku DLL. Podczas instalacji sterownika informacja o tej bibliotece DLL (ścieżka do pliku) zapisywana jest w rejestrze systemu Windows.
Twoja aplikacja powinna:
LoadLibrary (w systemie Windows).Po załadowaniu biblioteki DLL i uzyskaniu wskaźników do funkcji typowa sesja diagnostyczna wygląda tak:
PassThruOpen(), aby zainicjalizować komunikację z urządzeniem fizycznym. W odpowiedzi otrzymasz DeviceID — unikalny identyfikator tej sesji.
// Przykład
unsigned long deviceID;
long result = PassThruOpen(NULL, &deviceID);
PassThruConnect(), aby ustanowić logiczny kanał komunikacji z pojazdem za pomocą określonego protokołu (na przykład ISO15765 dla magistrali CAN). Wskazujesz
protokół, prędkość i inne parametry. W odpowiedzi otrzymujesz ChannelID.
// Przykład
unsigned long channelID;
result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
PassThruStartMsgFilter().
Proces wymiany danych jest asynchroniczny i oparty na kolejkach:
PassThruWriteMsg() nie wysyła komunikatu do magistrali natychmiast. Zamiast tego umieszcza jeden lub kilka komunikatów w kolejce do wysłania i od razu zwraca sterowanie.
Sterownik adaptera samodzielnie wyśle te komunikaty z kolejki, gdy tylko pojawi się taka możliwość.PassThruReadMsg() służy do pobierania komunikatów z tej kolejki.Ważna uwaga: Biblioteka J2534 jest jednowątkowa. Oznacza to, że wszystkie wywołania funkcji (PassThruWriteMsg, PassThruReadMsg i in.) dla jednego kanału muszą być wykonywane ściśle sekwencyjnie.
Nie można wywołać jednej funkcji, dopóki nie zakończy się wykonanie poprzedniej. Próba jednoczesnego wywołania funkcji z różnych wątków dla tego samego kanału doprowadzi do nieprzewidywalnego zachowania.
PassThruDisconnect().
// Przykład
result = PassThruDisconnect(channelID);
PassThruClose(), aby zwolnić urządzenie.
// Przykład
result = PassThruClose(deviceID);
Ta pętla to podstawa każdej aplikacji J2534. W kolejnych sekcjach szczegółowo opisano każdą funkcję API i jej parametry.
Każda funkcja J2534 API zwraca kod stanu. Pomyślne wykonanie zawsze zwraca STATUS_NOERROR (wartość 0). Każda inna wartość wskazuje na konkretny błąd (na przykład ERR_TIMEOUT, ERR_INVALID_CHANNEL_ID itd.).
Niezwykle ważne jest sprawdzanie zwracanej wartości po każdym wywołaniu funkcji.
Szczególny kod błędu — ERR_FAILED. To ogólny, niespecyficzny błąd. Tylko w tym przypadku należy wywołać funkcję PassThruGetLastError(), aby uzyskać od sterownika bardziej szczegółowy, tekstowy opis
problemu.
// Przykład prawidłowej obsługi błędów
long result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
if (result != STATUS_NOERROR)
{
printf("Błąd PassThruConnect. Kod: %ld\n", result);
// Jeśli błąd jest ogólny, żądamy szczegółów
if (result == ERR_FAILED)
{
char errorDescription[80];
PassThruGetLastError(&errorDescription[0], 80);
printf(" Informacje dodatkowe: %s\n", errorDescription);
}
// Tutaj może znajdować się logika obsługi innych kodów błędów
// switch (result) { case ERR_TIMEOUT: ... }
return; // Przerywamy wykonanie
}
Szczegółowy opis każdej funkcji standardu J2534 został wydzielony do dokumentacji funkcji.