Última modificación:
J2534 (a menudo denominado Pass-Thru) es un estándar desarrollado por SAE (Society of Automotive Engineers) que resuelve un problema importante: permite que el mismo software de diagnóstico funcione con adaptadores de diagnóstico de distintos fabricantes.
Idea principal:
Imagine que escribe un programa para la diagnosis de automóviles. Sin el estándar J2534, tendría que escribir un código distinto para cada adaptador (K-Line, adaptador CAN, etc.) que desee admitir. Esto es complicado y costoso.
El estándar J2534 define una API (interfaz de programación) uniforme que los fabricantes de adaptadores deben implementar en sus controladores. El estándar define esta API únicamente como una biblioteca DLL para Windows
Para el desarrollador esto significa:
PassThruOpen, PassThruReadMsg).De este modo, J2534 es un «puente» entre su aplicación y el adaptador de diagnóstico que oculta la complejidad del hardware concreto y permite centrarse en la lógica del diagnóstico.
Muchos desarrolladores, además de Windows, desean utilizar plataformas alternativas. Aparte de la biblioteca DLL estándar para Windows, ofrecemos también bibliotecas para Linux, macOS, así como para las plataformas móviles Android e iOS.
Es importante comprender que J2534 es un estándar de la capa de transporte. Se encarga de todo el trabajo de enviar y recibir bytes de datos a través de la interfaz física elegida (CAN, K-Line, etc.).
Sin embargo, el estándar J2534 no define:
Esto sigue siendo tarea de su aplicación. Usted, como desarrollador, debe saber exactamente qué bytes hay que enviar para solicitar, por ejemplo, los códigos de error o los parámetros actuales, y cómo analizar la respuesta de la unidad de control.
Para ello necesitará conocer los protocolos de diagnóstico de aplicación, tales como:
La DLL J2534 entregará sus bytes a la ECU, pero qué bytes son y qué hacer con la respuesta lo decide su programa.
El estándar J2534 forma parte de una gran familia de estándares que regulan la diagnosis del automóvil. Para una comprensión profunda se recomienda consultar los documentos oficiales.
Tabla detallada de la relación entre protocolos y estándares
El adaptador ScanDoc no implementa la versión completa del estándar J2534-1 y algunas extensiones de J2534-2, además de disponer de sus propias funciones para ampliar las posibilidades.
El estándar J2534 define un conjunto de protocolos de la capa física y de transporte a través de los cuales se realiza el intercambio de datos con la ECU del vehículo. A continuación se describe cada protocolo compatible con el adaptador ScanDoc.
Protocolo principal para la diagnosis de los automóviles modernos. ISO 15765 (conocido también como ISO-TP) implementa la capa de transporte sobre el bus CAN: realiza automáticamente la segmentación de mensajes largos en tramas CAN, el control de flujo (Flow Control) y el ensamblaje de la respuesta a partir de varias tramas.
Precisamente este protocolo se utiliza para la diagnosis mediante UDS (ISO 14229) y OBD-II en el bus CAN. Si su tarea consiste en enviar consultas de diagnóstico y recibir respuestas de la ECU, utilice ISO15765.
CAN_29BIT_IDFLOW_CONTROL_FILTER (hasta 16 por canal)ISO15765_ADDR_TYPE// Conexión mediante ISO 15765 a 500 kbit/s
PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
El protocolo CAN proporciona acceso al flujo en bruto de tramas CAN sin capa de transporte. Cada mensaje es una sola trama CAN (hasta 8 bytes de datos). El adaptador no realiza la segmentación ni el ensamblaje — usted recibe y envía las tramas
tal cual.
Utilice este protocolo cuando necesite trabajar directamente con el bus CAN: monitorización del tráfico, envío de tramas individuales, trabajo con protocolos no estándar sobre CAN.
CAN_29BIT_IDPASS_FILTER y BLOCK_FILTER (hasta 10 de cada tipo)// Conexión CAN a 500 kbit/s con ID de 29 bits
PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &channelID);
Protocolo de diagnosis por K-Line, ampliamente utilizado en automóviles de la década de 2000 (especialmente europeos). Admite dos formas de inicialización de la conexión: de 5 baudios (lenta) y rápida (fast init). Tras la inicialización, el intercambio se realiza a la velocidad acordada con la ECU.
Se utiliza para la diagnosis de concesionario mediante KWP2000 y para OBD-II por K-Line.
FIVE_BAUD_INIT) o rápida (FAST_INIT) mediante PassThruIoctlISO9141_K_LINE: si está establecido, inicialización solo por K-Line (sin L-Line)SET_CONFIG// Conexión mediante ISO 14230 a 10400 baudios, solo K-Line
PassThruConnect(deviceID, ISO14230, ISO9141_K_LINE, 10400, &channelID);
Protocolo de K-Line anterior, definido por el estándar ISO 9141-2. Se utiliza para la diagnosis OBD-II en automóviles más antiguos (hasta 2004-2008 según la región). Solo admite la inicialización de 5 baudios.
FIVE_BAUD_INIT// Conexión mediante ISO 9141 a 10400 baudios
PassThruConnect(deviceID, ISO9141, 0, 10400, &channelID);
Protocolo con modulación de ancho de pulso variable (Variable Pulse Width), utilizado en los automóviles de General Motors para la diagnosis OBD-II. Funciona a una velocidad de 10,4 kbit/s por un solo cable.
// Conexión mediante J1850 VPW
PassThruConnect(deviceID, J1850VPW, 0, 10400, &channelID);
Protocolo con modulación de ancho de pulso (Pulse Width Modulation), utilizado en los automóviles de Ford para la diagnosis OBD-II. Funciona a una velocidad de 41,6 kbit/s por dos cables.
// Conexión mediante J1850 PWM
PassThruConnect(deviceID, J1850PWM, 0, 41600, &channelID);
El trabajo con un adaptador J2534 desde su aplicación suele seguir este algoritmo:
Cada fabricante de adaptadores J2534 proporciona su implementación de la API en forma de archivo DLL. Al instalar el controlador, la información sobre esta DLL (la ruta al archivo) se escribe en el registro de Windows.
Su aplicación debe:
LoadLibrary (en Windows).Tras cargar la DLL y obtener los punteros a las funciones, una sesión de diagnóstico típica tiene este aspecto:
PassThruOpen() para inicializar la comunicación con el dispositivo físico. Como respuesta obtendrá un DeviceID — un identificador único de esta sesión.
// Ejemplo
unsigned long deviceID;
long result = PassThruOpen(NULL, &deviceID);
PassThruConnect() para establecer un canal lógico de comunicación con el vehículo mediante un protocolo determinado (por ejemplo, ISO15765 para el bus CAN). Usted indica
el protocolo, la velocidad y otros parámetros. Como respuesta obtiene un ChannelID.
// Ejemplo
unsigned long channelID;
result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
PassThruStartMsgFilter().
El proceso de intercambio de datos es asíncrono y se basa en colas:
PassThruWriteMsg() no envía el mensaje al bus de inmediato. En su lugar, coloca uno o varios mensajes en la cola de envío y devuelve el control enseguida.
El controlador del adaptador enviará por sí mismo esos mensajes de la cola en cuanto surja la posibilidad.PassThruReadMsg() se utiliza para extraer los mensajes de esa cola.Observación importante: La biblioteca J2534 es de un solo hilo. Esto significa que todas las llamadas a las funciones (PassThruWriteMsg, PassThruReadMsg, etc.) para un mismo canal deben ejecutarse de forma estrictamente secuencial.
No se puede llamar a una función hasta que no haya finalizado la ejecución de la anterior. El intento de llamar simultáneamente a funciones desde distintos hilos para un mismo canal provocará un comportamiento impredecible.
PassThruDisconnect().
// Ejemplo
result = PassThruDisconnect(channelID);
PassThruClose() para liberar el dispositivo.
// Ejemplo
result = PassThruClose(deviceID);
Este bucle es la base de cualquier aplicación J2534. En las siguientes secciones se describe en detalle cada función de la API y sus parámetros.
Cada función de la API J2534 devuelve un código de estado. La ejecución correcta siempre devuelve STATUS_NOERROR (valor 0). Cualquier otro valor indica un error concreto (por ejemplo, ERR_TIMEOUT, ERR_INVALID_CHANNEL_ID etc.).
Es sumamente importante comprobar el valor devuelto después de cada llamada a una función.
Un código de error especial es ERR_FAILED. Es un error general e inespecífico. Solo en este caso hay que llamar a la función PassThruGetLastError() para obtener del controlador una descripción textual más detallada
del problema.
// Ejemplo de tratamiento correcto de errores
long result = PassThruConnect(deviceID, ISO15765, 0, 500000, &channelID);
if (result != STATUS_NOERROR)
{
printf("Error de PassThruConnect. Código: %ld\n", result);
// Si el error es general, solicitamos los detalles
if (result == ERR_FAILED)
{
char errorDescription[80];
PassThruGetLastError(&errorDescription[0], 80);
printf(" Información adicional: %s\n", errorDescription);
}
// Aquí puede ir la lógica de tratamiento de otros códigos de error
// switch (result) { case ERR_TIMEOUT: ... }
return; // Interrumpimos la ejecución
}
La descripción detallada de cada función del estándar J2534 se ha trasladado a la referencia de funciones.