Quantex GmbH
DE RU EN EL
Ваш регион: Европа

PassThruReadMsgs v4.04 v5.0

Чтение принятых сообщений

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

Описание

Функция вычитывает из очереди канала принятые сообщения. Адаптер может принять максимум 100 сообщений на одну очередь для одного канала и имеет 64 Кбайт свободной памяти для всех очередей. При заполнении очереди или всей свободной памяти приём сообщений приостанавливается.

long PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG* pMsg, unsigned long* pNumMsgs, unsigned long Timeout)
Важно: Для протоколов ISO 9141, ISO 14230, на каждый принятый пакет, а в ISO 15765 на каждый сегментируемый пакет, генерируется сообщение-индикатор START_OF_MESSAGE с отметкой времени начала приёма. За ним следует основное сообщение с отметкой времени конца приёма.

Параметры

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

Код Описание Возможные причины и решения
STATUS_NOERROR Функция выполнена успешно -
ERR_CONCURRENT_API_CALL v5.0 Параллельный вызов API
  • Функция SAE J2534 API вызвана до завершения предыдущего вызова
  • Решение: дождитесь завершения предыдущего вызова перед новым
ERR_DEVICE_NOT_OPEN v5.0 Устройство не открыто
  • PassThruOpen не был успешно вызван
  • Решение: вызовите PassThruOpen перед использованием
ERR_DEVICE_NOT_CONNECTED Нет соединения с адаптером
  • Адаптер выключен или потеряна связь
  • Решение: проверьте питание адаптера и сетевое соединение
ERR_INVALID_DEVICE_ID Неверный идентификатор устройства
  • DeviceID не был получен через PassThruOpen
  • Решение: проверьте, что устройство открыто
ERR_INVALID_CHANNEL_ID Неверный идентификатор канала
  • ChannelID не был получен через PassThruConnect
  • Канал уже закрыт
  • Решение: проверьте, что канал открыт
ERR_NOT_SUPPORTED v5.0 Функция не поддерживается
  • Устройство не поддерживает эту функцию API для данного ChannelID
  • Решение: проверьте возможности устройства
ERR_NULL_PARAMETER Не задан указатель на буфер
  • pMsg или pNumMsgs равен NULL
  • Решение: передайте корректные указатели
ERR_TIMEOUT Истёк таймаут ожидания
  • За указанное время пришло меньше сообщений, чем запрошено
  • Решение: это штатная ситуация, проверьте pNumMsgs для количества принятых
ERR_BUFFER_EMPTY Приёмная очередь пуста
  • Нет сообщений в очереди при Timeout = 0
  • Решение: повторите запрос позже или используйте ненулевой таймаут
ERR_BUFFER_OVERFLOW Приёмная очередь была переполнена
  • Сообщения были потеряны из-за переполнения
  • Решение: вычитывайте сообщения чаще или увеличьте частоту опроса
ERR_BUFFER_TOO_SMALL v5.0 Буфер слишком мал
  • Размер DataBuffer в структуре PASSTHRU_MSG слишком мал для полного сообщения
  • Решение: увеличьте размер буфера данных
ERR_NO_FLOW_CONTROL Не установлен фильтр Flow Control
  • Для ISO 15765 требуется Flow Control фильтр
  • Решение: вызовите PassThruStartMsgFilter с типом FLOW_CONTROL_FILTER
ERR_FAILED Внутренняя ошибка
  • Ошибка выделения памяти или сбой стека
  • Решение: используйте PassThruGetLastError() для деталей

Примеры

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

#include "j2534_dll.hpp"

unsigned long ChannelID; // ID, полученный от PassThruConnect
PASSTHRU_MSG Msgs[10];   // Буфер для сообщений
unsigned long NumMsgs = 10; // Запрашиваем до 10 сообщений
unsigned long Timeout = 1000; // Таймаут 1000 мс

long ret = PassThruReadMsgs(ChannelID, &Msgs[0], &NumMsgs, Timeout);
if (ret == STATUS_NOERROR || ret == ERR_TIMEOUT)
{
    // Обработка полученных сообщений (NumMsgs штук)
    for (unsigned long i = 0; i < NumMsgs; i++) {
        if (Msgs[i].RxStatus & START_OF_MESSAGE) {
            // Индикатор начала сообщения
            continue;
        }
        // Обработка данных Msgs[i].Data, Msgs[i].DataSize
    }
}
else
{
    char error[256];
    PassThruGetLastError(error);
    printf("Error: %s\n", error);
}

Пример на Kotlin (Android)

// channelID получен ранее от ptConnect
val numMsgsToRead = 10
val timeout = 1000 // мс

val result = j2534.ptReadMsgs(channelID, numMsgsToRead, timeout)
if (result.status == STATUS_NOERROR || result.status == ERR_TIMEOUT) {
    // Успешно прочитано result.msgs.size сообщений
    for (msg in result.msgs) {
        if (msg.rxStatus and START_OF_MESSAGE != 0) {
            continue // Пропускаем индикатор начала
        }
        Log.i("J2534", "Получено: ${msg.data.toHexString()}")
    }
} else {
    Log.e("J2534", "Ошибка чтения: ${result.status}")
}

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

from ctypes import *
import platform

# Загрузка библиотеки
if platform.system() == "Windows":
    j2534 = windll.LoadLibrary("j2534sd_v04_04_x64.dll")
elif platform.system() == "Darwin":
    j2534 = cdll.LoadLibrary("libj2534_v04_04.dylib")
else:
    j2534 = cdll.LoadLibrary("libj2534_v04_04.so")

# Структура PASSTHRU_MSG
class PASSTHRU_MSG(Structure):
    _fields_ = [
        ("ProtocolID", c_ulong),
        ("RxStatus", c_ulong),
        ("TxFlags", c_ulong),
        ("Timestamp", c_ulong),
        ("DataSize", c_ulong),
        ("ExtraDataIndex", c_ulong),
        ("Data", c_ubyte * 4128)
    ]

# channel_id получен ранее от PassThruConnect
msgs = (PASSTHRU_MSG * 10)()
num_msgs = c_ulong(10)
timeout = c_ulong(1000)

ret = j2534.PassThruReadMsgs(channel_id, byref(msgs[0]), byref(num_msgs), timeout)

if ret == 0 or ret == 0x09:  # STATUS_NOERROR or ERR_TIMEOUT
    print(f"Получено {num_msgs.value} сообщений")
    for i in range(num_msgs.value):
        if msgs[i].RxStatus & 0x02:  # START_OF_MESSAGE
            continue
        data = bytes(msgs[i].Data[:msgs[i].DataSize])
        print(f"Данные: {data.hex()}")
else:
    error = create_string_buffer(256)
    j2534.PassThruGetLastError(error)
    print(f"Ошибка: {error.value.decode()}")

Пример на C# (P/Invoke)

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct PASSTHRU_MSG
{
    public uint ProtocolID;
    public uint RxStatus;
    public uint TxFlags;
    public uint Timestamp;
    public uint DataSize;
    public uint ExtraDataIndex;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4128)]
    public byte[] Data;
}

class J2534
{
    [DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern int PassThruReadMsgs(
        uint ChannelID,
        [In, Out] PASSTHRU_MSG[] pMsg,
        ref uint pNumMsgs,
        uint Timeout);

    [DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern int PassThruGetLastError(
        [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pErrorDescription);
}

// Использование:
// channelId получен ранее от PassThruConnect
PASSTHRU_MSG[] msgs = new PASSTHRU_MSG[10];
for (int i = 0; i < msgs.Length; i++)
    msgs[i].Data = new byte[4128];

uint numMsgs = 10;
uint timeout = 1000;

int ret = J2534.PassThruReadMsgs(channelId, msgs, ref numMsgs, timeout);

if (ret == 0 || ret == 0x09) // STATUS_NOERROR or ERR_TIMEOUT
{
    Console.WriteLine($"Получено {numMsgs} сообщений");
    for (uint i = 0; i < numMsgs; i++)
    {
        if ((msgs[i].RxStatus & 0x02) != 0) // START_OF_MESSAGE
            continue;
        byte[] data = new byte[msgs[i].DataSize];
        Array.Copy(msgs[i].Data, data, msgs[i].DataSize);
        Console.WriteLine($"Данные: {BitConverter.ToString(data)}");
    }
}
else
{
    var error = new System.Text.StringBuilder(256);
    J2534.PassThruGetLastError(error);
    Console.WriteLine($"Ошибка: {error}");
}