Создание логического канала связи поверх физического соединения
Последнее изменение:
Функция создаёт логический канал связи с автомобилем на указанном устройстве pass-thru. Логический канал накладывает дополнительную схему протокола поверх существующего физического канала связи.
При успешном выполнении функция возвращает STATUS_NOERROR, а значение по указателю pChannelID
используется как дескриптор (handle) для созданного канала. Канал находится в инициализированном состоянии.
Допускается до 10 логических каналов на один физический канал связи. Создание логического канала не влияет на работу физического канала и других связанных с ним логических каналов.
long PassThruLogicalConnect(
unsigned long PhysicalChannelID,
unsigned long ProtocolID,
unsigned long Flags,
void *pChannelDescriptor,
unsigned long *pChannelID
)
Созданный логический канал имеет следующее начальное состояние:
Входной параметр. Идентификатор физического канала, полученный при вызове PassThruConnect().
Входной параметр. Идентификатор протокола для логического канала связи.
Определяет, как логический канал будет взаимодействовать с автомобилем, а также тип структуры pChannelDescriptor.
| ProtocolID | Описание |
|---|---|
ISO15765_LOGICAL |
ISO 15765-2 с управлением потоком (flow control) |
Входной параметр. Флаги конфигурации логического канала. Флаги могут комбинироваться через 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 = маскирование включено |
Входной параметр. Указатель на структуру, описывающую конечные точки логического соединения.
Если указатель NULL, функция вернёт ERR_NULL_PARAMETER.
Входной параметр. Указатель на переменную unsigned long, выделенную приложением.
При успешном выполнении переменная будет содержать идентификатор логического канала для последующих вызовов функций.
Для протокола 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;
Допустимые флаги для дескриптора канала ISO 15765:
| Флаг | Применение | Описание |
|---|---|---|
CAN_29BIT_ID |
LocalAddress, RemoteAddress | Использовать 29-битный CAN ID (вместо 11-битного) |
ISO15765_ADDR_TYPE |
LocalAddress, RemoteAddress | Использовать расширенную адресацию (extended address) |
ISO15765_FRAME_PAD |
RemoteAddress | Включить паддинг кадров flow control при передаче |
Address[0] — CAN ID биты 28-24 (три старших бита должны быть нулевыми)Address[1] — CAN ID биты 23-16Address[2] — CAN ID биты 15-8Address[3] — CAN ID биты 7-0Address[4] — расширенный адрес (если указан флаг ISO15765_ADDR_TYPE)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() для получения описания. |
#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);
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)
PassThruConnect() - Создание физического соединенияPassThruLogicalDisconnect() - Закрытие логического каналаPassThruReadMsgs() - Чтение сообщений из канала