Последнее изменение:
J2534 (часто называемый Pass-Thru) — это стандарт, разработанный SAE (Обществом автомобильных инженеров), который решает важную задачу: он позволяет одному и тому же программному обеспечению для диагностики работать с диагностическими адаптерами от разных производителей.
Основная идея:
Представьте, что вы пишете программу для диагностики автомобилей. Без стандарта J2534 вам пришлось бы писать уникальный код для каждого адаптера (K-Line, CAN-адаптер и т.д.), который вы хотите поддержать. Это сложно и дорого.
Стандарт J2534 определяет единый API (программный интерфейс), который производители адаптеров должны реализовать в своих драйверах. Стандарт определяет этот API только как DLL-библиотеку для Windows
Для разработчика это означает:
PassThruOpen, PassThruReadMsg).Таким образом, J2534 — это "мост" между вашим приложением и диагностическим адаптером, который скрывает сложности конкретного оборудования и позволяет сосредоточиться на логике диагностики.
Многие разработчики, кроме Windows, хотят использовать альтернативные платформы. Мы предлагаем помимо стандартной DLL для Windows, также библиотеки для Linux, macOS, а также мобильных платформ Android и iOS.
Важно понимать, что J2534 — это стандарт для транспортного уровня. Он берёт на себя всю работу по отправке и приёму байтов данных по выбранному физическому интерфейсу (CAN, K-Line и т.д.).
Однако, стандарт J2534 не определяет:
Это остаётся задачей вашего приложения. Вы, как разработчик, должны знать, какие именно байты нужно отправить, чтобы запросить, например, коды ошибок или текущие параметры, и как разобрать ответ от блока управления.
Для этого вам потребуются знания прикладных протоколов диагностики, таких как:
J2534 DLL доставит ваши байты до ЭБУ, но что это за байты и что делать с ответом — решает ваша программа.
Стандарт J2534 является частью большого семейства стандартов, регулирующих автомобильную диагностику. Для глубокого понимания рекомендуется ознакомиться с официальными документами.
Подробная таблица соотношения протоколов и стандартов
Адаптер ScanDoc реализует не полный вариант стандарта J2534-1 и некоторые расширения из J2534-2, а также имеет собственные функции для расширения возможностей.
Стандарт J2534 определяет набор протоколов физического и транспортного уровня, через которые происходит обмен данными с ЭБУ автомобиля. Ниже описан каждый протокол, поддерживаемый адаптером 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 кбит/с
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
Протокол CAN предоставляет доступ к необработанному потоку CAN-кадров без транспортного уровня. Каждое сообщение — это один CAN-кадр (до 8 байт данных). Адаптер не выполняет сегментацию и сборку — вы получаете и отправляете кадры как есть.
Используйте этот протокол, когда вам нужно работать с CAN-шиной напрямую: мониторинг трафика, отправка отдельных кадров, работа с нестандартными протоколами поверх CAN.
CAN_29BIT_IDPASS_FILTER и BLOCK_FILTER (до 10 каждого типа)// Подключение CAN на 500 кбит/с с 29-битными ID
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);
Протокол диагностики по K-линии, широко применяемый в автомобилях 2000-х годов (особенно европейских). Поддерживает два способа инициализации соединения: 5-бодовую (медленную) и быструю (fast init). После инициализации обмен идёт на скорости, согласованной с ЭБУ.
Используется для дилерской диагностики по KWP2000 и для OBD-II на K-линии.
FIVE_BAUD_INIT) или быстрая (FAST_INIT) через PassThruIoctlISO9141_K_LINE: если установлен, инициализация только по K-линии (без L-линии)SET_CONFIG// Подключение по ISO 14230 на 10400 бод, только K-линия
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);
Более ранний протокол K-линии, определённый стандартом ISO 9141-2. Используется для OBD-II диагностики в старых автомобилях (до 2004-2008 годов в зависимости от региона). Поддерживает только 5-бодовую инициализацию.
FIVE_BAUD_INIT// Подключение по ISO 9141 на 10400 бод
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);
Протокол с модуляцией переменной ширины импульса (Variable Pulse Width), использовавшийся в автомобилях General Motors для OBD-II диагностики. Работает на скорости 10,4 кбит/с по одному проводу.
// Подключение по J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);
Протокол с модуляцией ширины импульса (Pulse Width Modulation), использовавшийся в автомобилях Ford для OBD-II диагностики. Работает на скорости 41,6 кбит/с по двум проводам.
// Подключение по 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 и её параметры.
Каждая функция J2534 API возвращает код состояния. Успешное выполнение всегда возвращает 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 вынесено в справочник функций.