Quantex GmbH
Ваш регион: Европа

PassThruLogicalConnect v5.0

Создание логического канала связи поверх физического соединения

Последнее изменение:

Описание

Функция создаёт логический канал связи с автомобилем на указанном устройстве pass-thru. Логический канал накладывает дополнительную схему протокола поверх существующего физического канала связи.

При успешном выполнении функция возвращает STATUS_NOERROR, а значение по указателю pChannelID используется как дескриптор (handle) для созданного канала. Канал находится в инициализированном состоянии.

Допускается до 10 логических каналов на один физический канал связи. Создание логического канала не влияет на работу физического канала и других связанных с ним логических каналов.

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

Инициализированное состояние канала

Созданный логический канал имеет следующее начальное состояние:

Параметры

PhysicalChannelID

Входной параметр. Идентификатор физического канала, полученный при вызове PassThruConnect().

ProtocolID

Входной параметр. Идентификатор протокола для логического канала связи. Определяет, как логический канал будет взаимодействовать с автомобилем, а также тип структуры pChannelDescriptor.

ProtocolID Описание
ISO15765_LOGICAL ISO 15765-2 с управлением потоком (flow control)

Flags

Входной параметр. Флаги конфигурации логического канала. Флаги могут комбинироваться через OR.

Флаг Описание Значения
FULL_DUPLEX Режим дуплекса канала. Только для ISO 15765. 0 = полудуплекс
1 = полный дуплекс
ISO15765_ON_J1939 Маскирование битов приоритета (28-26) в CAN ID для ISO 15765 сообщений с 29-битным идентификатором (согласно ISO 15765-2 Annex A и SAE J1939-21). Только для ISO 15765. 0 = маскирование выключено (стандартная обработка ISO 15765)
1 = маскирование включено

pChannelDescriptor

Входной параметр. Указатель на структуру, описывающую конечные точки логического соединения. Если указатель NULL, функция вернёт ERR_NULL_PARAMETER.

pChannelID

Входной параметр. Указатель на переменную unsigned long, выделенную приложением. При успешном выполнении переменная будет содержать идентификатор логического канала для последующих вызовов функций.

Структура ISO15765_CHANNEL_DESCRIPTOR

Для протокола ISO15765_LOGICAL используется структура ISO15765_CHANNEL_DESCRIPTOR, определяющая конечные точки логического соединения:

typedef struct {
    unsigned long LocalTxFlags;     // TxFlags для LocalAddress
    unsigned long RemoteTxFlags;    // TxFlags для RemoteAddress
    unsigned char LocalAddress[5];  // CAN ID + extended address (локальная сторона)
    unsigned char RemoteAddress[5]; // CAN ID + extended address (удалённая сторона)
} ISO15765_CHANNEL_DESCRIPTOR;

LocalTxFlags и RemoteTxFlags

Допустимые флаги для дескриптора канала ISO 15765:

Флаг Применение Описание
CAN_29BIT_ID LocalAddress, RemoteAddress Использовать 29-битный CAN ID (вместо 11-битного)
ISO15765_ADDR_TYPE LocalAddress, RemoteAddress Использовать расширенную адресацию (extended address)
ISO15765_FRAME_PAD RemoteAddress Включить паддинг кадров flow control при передаче

Формат LocalAddress и RemoteAddress

Важно: Адреса LocalAddress и RemoteAddress должны быть уникальными. Ни один из адресов не должен совпадать с адресами других существующих логических каналов для данного физического канала. CAN ID расширенного адреса не должен совпадать с CAN ID без расширенного адреса.

Возвращаемые коды ошибок

Код Описание
STATUS_NOERROR Функция выполнена успешно
ERR_CONCURRENT_API_CALL Функция J2534 API вызвана до завершения предыдущего вызова
ERR_DEVICE_NOT_OPEN PassThruOpen() не был успешно вызван
ERR_INVALID_CHANNEL_ID Недопустимое значение PhysicalChannelID
ERR_DEVICE_NOT_CONNECTED Ошибка связи с устройством pass-thru. Устройство было отключено.
ERR_NOT_SUPPORTED DLL не поддерживает данную функцию
ERR_LOG_CHAN_NOT_ALLOWED Логический канал не разрешён для данной комбинации физического канала и ProtocolID
ERR_PROTOCOL_ID_NOT_SUPPORTED Значение ProtocolID не поддерживается (недопустимое или неизвестное)
ERR_FLAG_NOT_SUPPORTED Значения Flags недопустимы, неизвестны или не применимы для текущего канала
ERR_INVALID_CHANNEL_DESCRIPTOR Один или несколько элементов структуры pChannelDescriptor недопустимы или не применимы для текущего канала
ERR_NULL_REQUIRED Параметр, который должен быть NULL, не установлен в NULL
ERR_NULL_PARAMETER Передан NULL указатель вместо обязательного указателя
ERR_NOT_UNIQUE Попытка создать логический канал с адресами, дублирующими адреса существующего канала
ERR_EXCEEDED_LIMIT Превышено максимальное количество логических каналов для данного физического канала
ERR_FAILED Неопределённая ошибка. Используйте PassThruGetLastError() для получения описания.

Примеры

Пример на C/C++

#include "j2534_dll.hpp"

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

// Открываем устройство
long ret = PassThruOpen("ScanDoc", &deviceID);
if (ret != STATUS_NOERROR) return;

// Создаём физическое соединение CAN
ret = PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &physicalChannelID);
if (ret != STATUS_NOERROR) {
    PassThruClose(deviceID);
    return;
}

// Настраиваем дескриптор логического канала ISO 15765
ISO15765_CHANNEL_DESCRIPTOR channelDesc = {0};

// Локальный адрес (адаптер) - 0x18DA00F1 (функциональный запрос)
channelDesc.LocalTxFlags = CAN_29BIT_ID;
channelDesc.LocalAddress[0] = 0x18;
channelDesc.LocalAddress[1] = 0xDA;
channelDesc.LocalAddress[2] = 0x00;
channelDesc.LocalAddress[3] = 0xF1;

// Удалённый адрес (ECU) - 0x18DAF100 (ответ от 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;

// Создаём логический канал
ret = PassThruLogicalConnect(
    physicalChannelID,
    ISO15765_LOGICAL,
    0,  // Flags: полудуплекс
    &channelDesc,
    &logicalChannelID
);

if (ret == STATUS_NOERROR) {
    printf("Логический канал создан: %lu\n", logicalChannelID);

    // Теперь можно использовать logicalChannelID для PassThruReadMsgs/PassThruQueueMsgs

    // Закрываем логический канал
    PassThruLogicalDisconnect(logicalChannelID);
}

// Закрываем физический канал и устройство
PassThruDisconnect(physicalChannelID);
PassThruClose(deviceID);

Пример на Python (ctypes)

from ctypes import *

# Загрузка библиотеки
j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")

# Структура дескриптора канала
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()

# Открываем устройство
ret = j2534.PassThruOpen(b"ScanDoc", byref(device_id))
if ret != 0:
    print(f"Ошибка PassThruOpen: {ret}")
    exit()

# Создаём физическое соединение CAN (500 кбит/с, 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"Ошибка PassThruConnect: {ret}")
    j2534.PassThruClose(device_id)
    exit()

# Настраиваем дескриптор канала
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

# Создаём логический канал
ret = j2534.PassThruLogicalConnect(
    physical_channel_id,
    ISO15765_LOGICAL,
    0,
    byref(channel_desc),
    byref(logical_channel_id)
)

if ret == 0:
    print(f"Логический канал создан: {logical_channel_id.value}")
    # ...работа с каналом...
    j2534.PassThruLogicalDisconnect(logical_channel_id)
else:
    print(f"Ошибка: {ret}")

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

Связанные функции