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

PassThruSelect v5.0

Выбор каналов для мониторинга сообщений

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

Описание

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

Функция не возвращает управление до тех пор, пока не произойдёт одно из следующего:

long PassThruSelect(
    SCHANNELSET *ChannelSetPtr,
    unsigned long SelectType,
    unsigned long Timeout
)
Назначение: PassThruSelect позволяет приложению проверять и ожидать доступность сообщений на нескольких каналах без постоянного вызова PassThruReadMsgs. Это минимизирует обмен данными между приложением и устройством, повышая производительность.
Важно: PassThruSelect НЕ возвращает сами сообщения — только информацию о том, какие каналы имеют доступные сообщения. Для получения сообщений необходимо вызвать PassThruReadMsgs.

Параметры

ChannelSetPtr

Входной параметр. Указатель на структуру SCHANNELSET, выделенную приложением.

SelectType

Входной параметр. Указывает назначение выбора каналов. Единственное допустимое значение:

Значение Описание
READABLE_TYPE Мониторинг каналов на наличие доступных сообщений (входящих сообщений или индикаций)

Timeout

Входной параметр. Минимальное время ожидания (в миллисекундах) доступности нужного количества сообщений.

Структура SCHANNELSET

typedef struct {
    unsigned long ChannelCount;      // Количество каналов в списке
    unsigned long ChannelThreshold;  // Минимальное количество каналов с сообщениями
    unsigned long *ChannelList;      // Указатель на массив ID каналов
} SCHANNELSET;

Поля структуры

Поле Вход/Выход Описание
ChannelCount Вход/Выход При вызове: количество каналов в ChannelList.
При возврате: количество каналов, оставшихся в ChannelList (с доступными сообщениями).
ChannelThreshold Вход Минимальное количество каналов, которые должны иметь хотя бы одно доступное сообщение. Значение 0 — функция возвращается немедленно (эквивалентно Timeout = 0). Должно быть ≤ ChannelCount.
ChannelList Вход/Выход При вызове: указатель на массив ID каналов (физических и/или логических) для мониторинга.
При возврате: подмножество исходного списка — только каналы с доступными сообщениями (порядок не гарантирован).

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

Код Описание
STATUS_NOERROR Функция выполнена успешно. ChannelList содержит каналы с доступными сообщениями.
ERR_CONCURRENT_API_CALL Функция J2534 API вызвана до завершения предыдущего вызова
ERR_DEVICE_NOT_OPEN PassThruOpen() не был успешно вызван
ERR_NULL_PARAMETER ChannelSetPtr или ChannelList равен NULL
ERR_INVALID_CHANNEL_ID Один из ID каналов в ChannelList недействителен. Структура SCHANNELSET не изменяется.
ERR_DEVICE_NOT_CONNECTED Ошибка связи с устройством pass-thru. Устройство было отключено.
ERR_NOT_SUPPORTED DLL не поддерживает данную функцию
ERR_SELECT_TYPE_NOT_SUPPORTED Значение SelectType недопустимо или неизвестно
ERR_EXCEEDED_LIMIT Значение ChannelThreshold больше ChannelCount
ERR_BUFFER_EMPTY Нет доступных сообщений ни на одном из указанных каналов
ERR_TIMEOUT Таймаут истёк, и количество каналов с сообщениями меньше ChannelThreshold. Применяется только при ненулевом Timeout и наличии хотя бы одного сообщения.
ERR_FAILED Неопределённая ошибка. Используйте PassThruGetLastError() для получения описания.

Примеры

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

#include "j2534_dll.hpp"

// ID каналов, полученные из PassThruConnect/PassThruLogicalConnect
unsigned long canChannelID = ...;
unsigned long isoChannelID = ...;

// Массив каналов для мониторинга
unsigned long channels[2] = { canChannelID, isoChannelID };

// Структура для PassThruSelect
SCHANNELSET channelSet;
channelSet.ChannelCount = 2;
channelSet.ChannelThreshold = 1;  // Ждём хотя бы 1 канал с сообщением
channelSet.ChannelList = channels;

// Ожидаем сообщения до 1000 мс
long ret = PassThruSelect(&channelSet, READABLE_TYPE, 1000);

if (ret == STATUS_NOERROR) {
    printf("Каналов с сообщениями: %lu\n", channelSet.ChannelCount);

    // Читаем сообщения с каналов, у которых есть данные
    for (unsigned long i = 0; i < channelSet.ChannelCount; i++) {
        unsigned long channelID = channelSet.ChannelList[i];
        printf("Канал %lu имеет сообщения\n", channelID);

        // Читаем сообщения
        PASSTHRU_MSG msg[10];
        unsigned long numMsgs = 10;
        ret = PassThruReadMsgs(channelID, msg, &numMsgs, 0);
        // ...обработка сообщений...
    }
} else if (ret == ERR_BUFFER_EMPTY) {
    printf("Нет доступных сообщений\n");
} else if (ret == ERR_TIMEOUT) {
    printf("Таймаут, но есть %lu каналов с сообщениями\n", channelSet.ChannelCount);
} else {
    char error[256];
    PassThruGetLastError(error);
    printf("Ошибка: %s\n", error);
}

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

from ctypes import *

j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")

# Структура SCHANNELSET
class SCHANNELSET(Structure):
    _fields_ = [
        ("ChannelCount", c_ulong),
        ("ChannelThreshold", c_ulong),
        ("ChannelList", POINTER(c_ulong))
    ]

# ID каналов
can_channel_id = c_ulong(...)  # из PassThruConnect
iso_channel_id = c_ulong(...)  # из PassThruLogicalConnect

# Массив каналов
channels = (c_ulong * 2)(can_channel_id.value, iso_channel_id.value)

# Структура для PassThruSelect
channel_set = SCHANNELSET()
channel_set.ChannelCount = 2
channel_set.ChannelThreshold = 1
channel_set.ChannelList = channels

READABLE_TYPE = 0x01

# Ожидаем сообщения до 1000 мс
ret = j2534.PassThruSelect(byref(channel_set), READABLE_TYPE, 1000)

if ret == 0:  # STATUS_NOERROR
    print(f"Каналов с сообщениями: {channel_set.ChannelCount}")
    for i in range(channel_set.ChannelCount):
        print(f"Канал {channel_set.ChannelList[i]} имеет сообщения")
elif ret == 0x10:  # ERR_BUFFER_EMPTY
    print("Нет доступных сообщений")
elif ret == 0x09:  # ERR_TIMEOUT
    print(f"Таймаут, каналов с сообщениями: {channel_set.ChannelCount}")
else:
    error = create_string_buffer(256)
    j2534.PassThruGetLastError(error)
    print(f"Ошибка: {error.value.decode()}")

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