Quantex GmbH
Su región: Europa

PassThruLogicalConnect v5.0

Creación de un canal de comunicación lógico sobre una conexión física

Última modificación:

Descripción

La función crea un canal de comunicación lógico con el vehículo en el dispositivo pass-thru indicado. El canal lógico superpone un esquema de protocolo adicional sobre el canal de comunicación físico existente.

Tras una ejecución correcta, la función devuelve STATUS_NOERROR, y el valor apuntado por pChannelID se utiliza como descriptor (handle) del canal creado. El canal se encuentra en estado inicializado.

Se admiten hasta 10 canales lógicos por cada canal de comunicación físico. La creación de un canal lógico no afecta al funcionamiento del canal físico ni de otros canales lógicos asociados a él.

long PassThruLogicalConnect(
    unsigned long PhysicalChannelID,
    unsigned long ProtocolID,
    unsigned long Flags,
    void *pChannelDescriptor,
    unsigned long *pChannelID
)

Estado inicializado del canal

El canal lógico creado tiene el siguiente estado inicial:

Parámetros

PhysicalChannelID

Parámetro de entrada. Identificador del canal físico obtenido en la llamada a PassThruConnect().

ProtocolID

Parámetro de entrada. Identificador del protocolo para el canal de comunicación lógico. Determina cómo interactuará el canal lógico con el vehículo, así como el tipo de la estructura pChannelDescriptor.

ProtocolID Descripción
ISO15765_LOGICAL ISO 15765-2 con control de flujo (flow control)

Flags

Parámetro de entrada. Flags de configuración del canal lógico. Los flags pueden combinarse mediante OR.

Flag Descripción Valores
FULL_DUPLEX Modo dúplex del canal. Solo para ISO 15765. 0 = semidúplex
1 = dúplex completo
ISO15765_ON_J1939 Enmascaramiento de los bits de prioridad (28-26) en el CAN ID para mensajes ISO 15765 con identificador de 29 bits (conforme a ISO 15765-2 Annex A y SAE J1939-21). Solo para ISO 15765. 0 = enmascaramiento desactivado (procesamiento estándar de ISO 15765)
1 = enmascaramiento activado

pChannelDescriptor

Parámetro de entrada. Puntero a la estructura que describe los puntos finales de la conexión lógica. Si el puntero es NULL, la función devolverá ERR_NULL_PARAMETER.

pChannelID

Parámetro de entrada. Puntero a una variable unsigned long reservada por la aplicación. Tras una ejecución correcta, la variable contendrá el identificador del canal lógico para las llamadas posteriores a las funciones.

Estructura ISO15765_CHANNEL_DESCRIPTOR

Para el protocolo ISO15765_LOGICAL se utiliza la estructura ISO15765_CHANNEL_DESCRIPTOR, que define los puntos finales de la conexión lógica:

typedef struct {
    unsigned long LocalTxFlags;     // TxFlags para LocalAddress
    unsigned long RemoteTxFlags;    // TxFlags para RemoteAddress
    unsigned char LocalAddress[5];  // CAN ID + extended address (lado local)
    unsigned char RemoteAddress[5]; // CAN ID + extended address (lado remoto)
} ISO15765_CHANNEL_DESCRIPTOR;

LocalTxFlags y RemoteTxFlags

Flags permitidos para el descriptor del canal ISO 15765:

Flag Aplicación Descripción
CAN_29BIT_ID LocalAddress, RemoteAddress Usar CAN ID de 29 bits (en lugar de 11 bits)
ISO15765_ADDR_TYPE LocalAddress, RemoteAddress Usar direccionamiento extendido (extended address)
ISO15765_FRAME_PAD RemoteAddress Activar el relleno (padding) de las tramas de flow control en la transmisión

Formato de LocalAddress y RemoteAddress

Importante: Las direcciones LocalAddress y RemoteAddress deben ser únicas. Ninguna de las direcciones debe coincidir con las direcciones de otros canales lógicos existentes para el canal físico dado. El CAN ID con dirección extendida no debe coincidir con un CAN ID sin dirección extendida.

Códigos de error devueltos

Código Descripción
STATUS_NOERROR La función se ejecutó correctamente
ERR_CONCURRENT_API_CALL Se llamó a una función de la API J2534 antes de finalizar la llamada anterior
ERR_DEVICE_NOT_OPEN PassThruOpen() no se llamó correctamente
ERR_INVALID_CHANNEL_ID Valor de PhysicalChannelID no válido
ERR_DEVICE_NOT_CONNECTED Error de comunicación con el dispositivo pass-thru. El dispositivo se desconectó.
ERR_NOT_SUPPORTED La DLL no admite esta función
ERR_LOG_CHAN_NOT_ALLOWED El canal lógico no está permitido para la combinación dada de canal físico y ProtocolID
ERR_PROTOCOL_ID_NOT_SUPPORTED El valor de ProtocolID no es compatible (no válido o desconocido)
ERR_FLAG_NOT_SUPPORTED Los valores de Flags no son válidos, son desconocidos o no son aplicables al canal actual
ERR_INVALID_CHANNEL_DESCRIPTOR Uno o varios elementos de la estructura pChannelDescriptor no son válidos o no son aplicables al canal actual
ERR_NULL_REQUIRED Un parámetro que debería ser NULL no se estableció en NULL
ERR_NULL_PARAMETER Se pasó un puntero NULL en lugar de un puntero obligatorio
ERR_NOT_UNIQUE Intento de crear un canal lógico con direcciones que duplican las direcciones de un canal existente
ERR_EXCEEDED_LIMIT Se superó el número máximo de canales lógicos para el canal físico dado
ERR_FAILED Error no especificado. Utilice PassThruGetLastError() para obtener la descripción.

Ejemplos

Ejemplo en C/C++

#include "j2534_dll.hpp"

unsigned long deviceID = 0;
unsigned long physicalChannelID = 0;
unsigned long logicalChannelID = 0;

// Abrimos el dispositivo
long ret = PassThruOpen("ScanDoc", &deviceID);
if (ret != STATUS_NOERROR) return;

// Creamos la conexión física CAN
ret = PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &physicalChannelID);
if (ret != STATUS_NOERROR) {
    PassThruClose(deviceID);
    return;
}

// Configuramos el descriptor del canal lógico ISO 15765
ISO15765_CHANNEL_DESCRIPTOR channelDesc = {0};

// Dirección local (adaptador) - 0x18DA00F1 (solicitud funcional)
channelDesc.LocalTxFlags = CAN_29BIT_ID;
channelDesc.LocalAddress[0] = 0x18;
channelDesc.LocalAddress[1] = 0xDA;
channelDesc.LocalAddress[2] = 0x00;
channelDesc.LocalAddress[3] = 0xF1;

// Dirección remota (ECU) - 0x18DAF100 (respuesta del ECU)
channelDesc.RemoteTxFlags = CAN_29BIT_ID | ISO15765_FRAME_PAD;
channelDesc.RemoteAddress[0] = 0x18;
channelDesc.RemoteAddress[1] = 0xDA;
channelDesc.RemoteAddress[2] = 0xF1;
channelDesc.RemoteAddress[3] = 0x00;

// Creamos el canal lógico
ret = PassThruLogicalConnect(
    physicalChannelID,
    ISO15765_LOGICAL,
    0,  // Flags: semidúplex
    &channelDesc,
    &logicalChannelID
);

if (ret == STATUS_NOERROR) {
    printf("Canal lógico creado: %lu\n", logicalChannelID);

    // Ahora se puede usar logicalChannelID para PassThruReadMsgs/PassThruQueueMsgs

    // Cerramos el canal lógico
    PassThruLogicalDisconnect(logicalChannelID);
}

// Cerramos el canal físico y el dispositivo
PassThruDisconnect(physicalChannelID);
PassThruClose(deviceID);

Ejemplo en Python (ctypes)

from ctypes import *

# Carga de la biblioteca
j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")

# Estructura del descriptor del canal
class ISO15765_CHANNEL_DESCRIPTOR(Structure):
    _fields_ = [
        ("LocalTxFlags", c_ulong),
        ("RemoteTxFlags", c_ulong),
        ("LocalAddress", c_ubyte * 5),
        ("RemoteAddress", c_ubyte * 5)
    ]

device_id = c_ulong()
physical_channel_id = c_ulong()
logical_channel_id = c_ulong()

# Abrimos el dispositivo
ret = j2534.PassThruOpen(b"ScanDoc", byref(device_id))
if ret != 0:
    print(f"Error de PassThruOpen: {ret}")
    exit()

# Creamos la conexión física CAN (500 kbit/s, 29-bit ID)
CAN = 0x05
CAN_29BIT_ID = 0x100
ret = j2534.PassThruConnect(device_id, CAN, CAN_29BIT_ID, 500000, byref(physical_channel_id))
if ret != 0:
    print(f"Error de PassThruConnect: {ret}")
    j2534.PassThruClose(device_id)
    exit()

# Configuramos el descriptor del canal
ISO15765_LOGICAL = 0x200
ISO15765_FRAME_PAD = 0x40

channel_desc = ISO15765_CHANNEL_DESCRIPTOR()
channel_desc.LocalTxFlags = CAN_29BIT_ID
channel_desc.LocalAddress[0] = 0x18
channel_desc.LocalAddress[1] = 0xDA
channel_desc.LocalAddress[2] = 0x00
channel_desc.LocalAddress[3] = 0xF1

channel_desc.RemoteTxFlags = CAN_29BIT_ID | ISO15765_FRAME_PAD
channel_desc.RemoteAddress[0] = 0x18
channel_desc.RemoteAddress[1] = 0xDA
channel_desc.RemoteAddress[2] = 0xF1
channel_desc.RemoteAddress[3] = 0x00

# Creamos el canal lógico
ret = j2534.PassThruLogicalConnect(
    physical_channel_id,
    ISO15765_LOGICAL,
    0,
    byref(channel_desc),
    byref(logical_channel_id)
)

if ret == 0:
    print(f"Canal lógico creado: {logical_channel_id.value}")
    # ...trabajo con el canal...
    j2534.PassThruLogicalDisconnect(logical_channel_id)
else:
    print(f"Error: {ret}")

j2534.PassThruDisconnect(physical_channel_id)
j2534.PassThruClose(device_id)

Funciones relacionadas