Quantex GmbH
Twój region: Europa

PassThruIoctl v4.04 v5.0

Zarządzanie wejściem-wyjściem

Ostatnia zmiana:

Opis

Uniwersalna funkcja zarządzania urządzeniem i kanałem. Wykonuje różne operacje w zależności od parametru IoctlID: odczyt/zapis konfiguracji, inicjalizacja protokołów, czyszczenie buforów i inne operacje pomocnicze.

long PassThruIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)

Parametry

IoctlID Wartość Opis
GET_CONFIG 0x01 Odczyt parametrów protokołu
SET_CONFIG 0x02 Zapis parametrów protokołu
READ_VBATT 0x03 Odczyt napięcia zasilania
FIVE_BAUD_INIT 0x04 Inicjalizacja 5-bodowa K-Line
FAST_INIT 0x05 Inicjalizacja Fast K-Line
CLEAR_TX_BUFFER 0x07 Czyszczenie kolejki nadawczej
CLEAR_RX_BUFFER 0x08 Czyszczenie kolejki odbiorczej
CLEAR_PERIODIC_MSGS 0x09 Czyszczenie komunikatów okresowych
CLEAR_MSG_FILTERS 0x0A Czyszczenie wszystkich filtrów
CLEAR_FUNCT_MSG_LOOKUP_TABLE 0x0B Czyszczenie tablicy adresów funkcjonalnych
ADD_TO_FUNCT_MSG_LOOKUP_TABLE 0x0C Dodanie do tablicy adresów funkcjonalnych
DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE 0x0D Usunięcie z tablicy adresów funkcjonalnych
READ_PROG_VOLTAGE 0x0E Odczyt napięcia programowania
SW_CAN_HS 0x8000 Przełączenie SW-CAN w tryb wysokiej prędkości
SW_CAN_NS 0x8001 Przełączenie SW-CAN w tryb normalny
BUS_ON v5.0 0x0F Podłączenie kontrolera CAN do magistrali
REQUEST_CONNECTION J2534-2 0x800A Nawiązanie połączenia TP 2.0
TEARDOWN_CONNECTION J2534-2 0x800B Zerwanie połączenia TP 2.0
GET_DEVICE_INFO J2534-2 0x800C Pobranie informacji o urządzeniu
GET_PROTOCOL_INFO J2534-2 0x800D Pobranie informacji o protokole
ISO13400_PS Quantex 0x8110-0x8113 Polecenia DoIP (Diagnostics over IP)

Zwracane kody błędów

Kod Opis Możliwe przyczyny i rozwiązania
STATUS_NOERROR Funkcja wykonana pomyślnie
ERR_DEVICE_NOT_CONNECTED Brak połączenia z adapterem
  • Adapter wyłączony lub poza zasięgiem
  • Rozwiązanie: sprawdź zasilanie adaptera i połączenie sieciowe
ERR_INVALID_CHANNEL_ID Nieprawidłowy identyfikator kanału
  • ChannelID nie został uzyskany przez PassThruConnect lub kanał jest zamknięty
  • Rozwiązanie: upewnij się, że PassThruConnect zakończył się pomyślnie
ERR_INVALID_IOCTL_ID Nieprawidłowy identyfikator IoctlID
  • Podany IoctlID nie jest obsługiwany
  • Rozwiązanie: sprawdź poprawność wartości IoctlID
ERR_NULL_PARAMETER Przekazano NULL zamiast wymaganego wskaźnika
  • pInput lub pOutput jest równy NULL, gdy wymagany jest wskaźnik
  • Rozwiązanie: przekaż poprawne wskaźniki
ERR_NOT_SUPPORTED Operacja nieobsługiwana
  • Adapter nie obsługuje żądanej operacji
  • Rozwiązanie: sprawdź możliwości adaptera przez GET_DEVICE_INFO
ERR_INVALID_IOCTL_VALUE Niedopuszczalna wartość parametru
  • Wartość w pInput wykracza poza dopuszczalne granice
  • Rozwiązanie: sprawdź dopuszczalne zakresy wartości
ERR_INVALID_MSG Nieprawidłowa struktura komunikatu
  • Błędna struktura w pInput dla FAST_INIT
  • Rozwiązanie: sprawdź poprawność pól PASSTHRU_MSG
ERR_FAILED Nieokreślony błąd
  • Wewnętrzny błąd biblioteki lub adaptera
  • Rozwiązanie: wywołaj PassThruGetLastError(), aby uzyskać opis

READ_VBATT — Odczyt napięcia zasilania

Zwraca napięcie na złączu OBD-II (styk 16). Wartość w miliwoltach, aby uzyskać wolty, podziel przez 1000. Polecenie nie wymaga otwartego kanału i może być wykonane od razu po PassThruOpen.

pInput NULL
pOutput unsigned long* — napięcie w mV

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long DeviceID;  // Uzyskany z PassThruOpen
unsigned long voltage;
long ret;

ret = PassThruIoctl(DeviceID, READ_VBATT, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
    printf("Napięcie: %.2f V\n", voltage / 1000.0);
}

Przykład w Kotlin (Android)

// deviceID uzyskany wcześniej z ptOpen
val result = j2534.ptIoctl(deviceID, READ_VBATT, 0, null)
if (result.status == STATUS_NOERROR) {
    val voltageV = result.outputValue / 1000.0
    Log.i("J2534", "Napięcie: ${"%.2f".format(voltageV)} V")
}

Przykład w Python

from ctypes import *

voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_VBATT, None, byref(voltage))
if ret == 0:  # STATUS_NOERROR
    print(f"Napięcie: {voltage.value / 1000:.2f} V")

Przykład w C#

uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_VBATT, IntPtr.Zero, out voltage);
if (ret == 0)
{
    Console.WriteLine($"Napięcie: {voltage / 1000.0:F2} V");
}

READ_PROG_VOLTAGE — Odczyt napięcia programowania

Zwraca bieżące napięcie na wyjściu programowania. Wartość w miliwoltach, zaokrąglona do najbliższej dziesiątej części wolta.

pInput NULL
pOutput unsigned long* — napięcie w mV

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long DeviceID;
unsigned long voltage;
long ret;

ret = PassThruIoctl(DeviceID, READ_PROG_VOLTAGE, NULL, &voltage);
if (ret == STATUS_NOERROR)
{
    printf("Napięcie programowania: %.2f V\n", voltage / 1000.0);
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(deviceID, READ_PROG_VOLTAGE, 0, null)
if (result.status == STATUS_NOERROR) {
    val voltageV = result.outputValue / 1000.0
    Log.i("J2534", "Napięcie programowania: ${"%.2f".format(voltageV)} V")
}

Przykład w Python

from ctypes import *

voltage = c_ulong()
ret = j2534.PassThruIoctl(device_id, READ_PROG_VOLTAGE, None, byref(voltage))
if ret == 0:
    print(f"Napięcie programowania: {voltage.value / 1000:.2f} V")

Przykład w C#

uint voltage;
int ret = J2534.PassThruIoctl(deviceId, READ_PROG_VOLTAGE, IntPtr.Zero, out voltage);
if (ret == 0)
{
    Console.WriteLine($"Napięcie programowania: {voltage / 1000.0:F2} V");
}

FIVE_BAUD_INIT — Inicjalizacja 5-bodowa

Uruchamia wolną (5 bodów) inicjalizację dla protokołów ISO 9141 i ISO 14230 (K-Line). Odbiera KeyWord od ECU. Tryb inicjalizacji ustawiany jest parametrem FIVE_BAUD_MOD przez SET_CONFIG. Prędkość transmisji jest określana automatycznie.

pInput SBYTE_ARRAY* — adres inicjalizacji (1 bajt)
pOutput SBYTE_ARRAY* — KeyWord (2 bajty)
Parametr FIVE_BAUD_MOD określa tryb inicjalizacji: ISO9141-2/ISO14230-4 (0), inwersja KB2 (1), inwersja adresu (2), ISO9141 bez inwersji (3).

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Uzyskany z PassThruConnect
SBYTE_ARRAY InputMsg;
SBYTE_ARRAY OutputMsg;
long ret;

unsigned char initByte[1];
unsigned char keyWord[2];

initByte[0] = 0x33;  // Adres inicjalizacji ECU

InputMsg.NumOfBytes = 1;
InputMsg.BytePtr = initByte;
OutputMsg.NumOfBytes = 2;
OutputMsg.BytePtr = keyWord;

ret = PassThruIoctl(ChannelID, FIVE_BAUD_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
    printf("KeyWord: %02X %02X\n", keyWord[0], keyWord[1]);
}

Przykład w Kotlin (Android)

// channelID uzyskany z ptConnect dla ISO14230
val initAddress = byteArrayOf(0x33)  // Adres inicjalizacji

val result = j2534.ptFiveBaudInit(channelID, initAddress)
if (result.status == STATUS_NOERROR) {
    val keyWord = result.keyWord
    Log.i("J2534", "KeyWord: ${keyWord[0].toHex()} ${keyWord[1].toHex()}")
}

Przykład w Python

from ctypes import *

input_msg = SBYTE_ARRAY()
input_msg.NumOfBytes = 1
input_msg.BytePtr = (c_ubyte * 1)(0x33)

output_msg = SBYTE_ARRAY()
output_msg.NumOfBytes = 2
keyword = (c_ubyte * 2)()
output_msg.BytePtr = keyword

ret = j2534.PassThruIoctl(channel_id, FIVE_BAUD_INIT, byref(input_msg), byref(output_msg))
if ret == 0:
    print(f"KeyWord: {keyword[0]:02X} {keyword[1]:02X}")

Przykład w C#

var inputMsg = new SBYTE_ARRAY {
    NumOfBytes = 1,
    BytePtr = new byte[] { 0x33 }  // Adres inicjalizacji
};

var outputMsg = new SBYTE_ARRAY {
    NumOfBytes = 2,
    BytePtr = new byte[2]
};

int ret = J2534.PassThruIoctl(channelId, FIVE_BAUD_INIT, ref inputMsg, ref outputMsg);
if (ret == 0)
{
    Console.WriteLine($"KeyWord: {outputMsg.BytePtr[0]:X2} {outputMsg.BytePtr[1]:X2}");
}

FAST_INIT — Inicjalizacja Fast

Uruchamia szybką inicjalizację dla protokołu ISO 14230 (K-Line). Wysyła żądanie StartCommunication i zwraca odpowiedź ECU. Używana dla KWP2000.

pInput PASSTHRU_MSG* — żądanie inicjalizacji
pOutput PASSTHRU_MSG* — odpowiedź ECU
Ważne: Przy adresie funkcjonalnym (rozgłoszeniowym) na żądanie może odpowiedzieć kilka ECU. W pOutput znajdzie się tylko pierwsza odpowiedź, pozostałe trafią do kolejki odbiorczej.

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Uzyskany z PassThruConnect
PASSTHRU_MSG InputMsg;
PASSTHRU_MSG OutputMsg;
long ret;

// Żądanie StartCommunication
InputMsg.ProtocolID = ISO14230;
InputMsg.TxFlags = 0;
InputMsg.DataSize = 4;
InputMsg.Data[0] = 0x81;  // Format: adres fizyczny, 1 bajt danych
InputMsg.Data[1] = 0x10;  // Adres docelowy (ECU)
InputMsg.Data[2] = 0xF1;  // Adres źródłowy (tester)
InputMsg.Data[3] = 0x81;  // SID: StartCommunication

ret = PassThruIoctl(ChannelID, FAST_INIT, &InputMsg, &OutputMsg);
if (ret == STATUS_NOERROR)
{
    printf("Odpowiedź ECU: %d bajtów\n", OutputMsg.DataSize);
    for (int i = 0; i < OutputMsg.DataSize; i++)
        printf("%02X ", OutputMsg.Data[i]);
}

Przykład w Kotlin (Android)

// channelID uzyskany z ptConnect dla ISO14230
val request = PassThruMsg(
    protocolID = ISO14230,
    txFlags = 0u,
    dataSize = 4,
    data = byteArrayOf(0x81.toByte(), 0x10, 0xF1.toByte(), 0x81.toByte())
)

val result = j2534.ptFastInit(channelID, request)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "Odpowiedź ECU: ${result.response.data.toHexString()}")
}

Przykład w Python

from ctypes import *

input_msg = PASSTHRU_MSG()
input_msg.ProtocolID = ISO14230
input_msg.TxFlags = 0
input_msg.DataSize = 4
input_msg.Data[0] = 0x81  # Format
input_msg.Data[1] = 0x10  # Adres docelowy
input_msg.Data[2] = 0xF1  # Adres źródłowy
input_msg.Data[3] = 0x81  # SID: StartCommunication

output_msg = PASSTHRU_MSG()

ret = j2534.PassThruIoctl(channel_id, FAST_INIT, byref(input_msg), byref(output_msg))
if ret == 0:
    data = bytes(output_msg.Data[:output_msg.DataSize])
    print(f"Odpowiedź ECU: {data.hex(' ').upper()}")

Przykład w C#

var inputMsg = new PASSTHRU_MSG {
    ProtocolID = ISO14230,
    TxFlags = 0,
    DataSize = 4
};
inputMsg.Data[0] = 0x81;  // Format
inputMsg.Data[1] = 0x10;  // Adres docelowy
inputMsg.Data[2] = 0xF1;  // Adres źródłowy
inputMsg.Data[3] = 0x81;  // SID: StartCommunication

var outputMsg = new PASSTHRU_MSG();

int ret = J2534.PassThruIoctl(channelId, FAST_INIT, ref inputMsg, ref outputMsg);
if (ret == 0)
{
    var data = new byte[outputMsg.DataSize];
    Array.Copy(outputMsg.Data, data, outputMsg.DataSize);
    Console.WriteLine($"Odpowiedź ECU: {BitConverter.ToString(data).Replace("-", " ")}");
}

CLEAR_TX_BUFFER — Czyszczenie kolejki nadawczej

Usuwa wszystkie komunikaty z kolejki nadawczej kanału. Używane do anulowania zaplanowanych transmisji.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_TX_BUFFER, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    char error[256];
    PassThruGetLastError(error);
    printf("Błąd: %s\n", error);
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_TX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Błąd CLEAR_TX_BUFFER: ${result.status}")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_TX_BUFFER, None, None)
if ret != 0:
    print(f"Błąd CLEAR_TX_BUFFER: {ret}")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_TX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Błąd CLEAR_TX_BUFFER: {ret}");

CLEAR_RX_BUFFER — Czyszczenie kolejki odbiorczej

Usuwa wszystkie komunikaty z kolejki odbiorczej kanału. Zaleca się wywoływanie przed rozpoczęciem nowej sesji diagnostycznej.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_RX_BUFFER, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    char error[256];
    PassThruGetLastError(error);
    printf("Błąd: %s\n", error);
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_RX_BUFFER, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Błąd CLEAR_RX_BUFFER: ${result.status}")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_RX_BUFFER, None, None)
if ret != 0:
    print(f"Błąd CLEAR_RX_BUFFER: {ret}")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_RX_BUFFER, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Błąd CLEAR_RX_BUFFER: {ret}");

CLEAR_PERIODIC_MSGS — Czyszczenie komunikatów okresowych

Usuwa wszystkie komunikaty okresowe ustawione przez PassThruStartPeriodicMsg. Równoważne wywołaniu PassThruStopPeriodicMsg dla każdego komunikatu.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_PERIODIC_MSGS, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    char error[256];
    PassThruGetLastError(error);
    printf("Błąd: %s\n", error);
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_PERIODIC_MSGS, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Błąd CLEAR_PERIODIC_MSGS: ${result.status}")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_PERIODIC_MSGS, None, None)
if ret != 0:
    print(f"Błąd CLEAR_PERIODIC_MSGS: {ret}")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_PERIODIC_MSGS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Błąd CLEAR_PERIODIC_MSGS: {ret}");

CLEAR_MSG_FILTERS — Czyszczenie filtrów

Usuwa wszystkie filtry komunikatów ustawione przez PassThruStartMsgFilter. Po wywołaniu wszystkie przychodzące komunikaty będą blokowane do czasu ustawienia nowych filtrów.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_MSG_FILTERS, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    char error[256];
    PassThruGetLastError(error);
    printf("Błąd: %s\n", error);
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, CLEAR_MSG_FILTERS, 0, null)
if (result.status != STATUS_NOERROR) {
    Log.e("J2534", "Błąd CLEAR_MSG_FILTERS: ${result.status}")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_MSG_FILTERS, None, None)
if ret != 0:
    print(f"Błąd CLEAR_MSG_FILTERS: {ret}")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_MSG_FILTERS, IntPtr.Zero, IntPtr.Zero);
if (ret != 0)
    Console.WriteLine($"Błąd CLEAR_MSG_FILTERS: {ret}");

CLEAR_FUNCT_MSG_LOOKUP_TABLE — Czyszczenie tablicy adresów funkcjonalnych

Czyści tablicę adresów funkcjonalnych J1850. Używane dla protokołów J1850 PWM/VPW przy pracy z adresacją funkcjonalną.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał J1850
long ret;

ret = PassThruIoctl(ChannelID, CLEAR_FUNCT_MSG_LOOKUP_TABLE, NULL, NULL);
if (ret != STATUS_NOERROR)
{
    // Obsługa błędu
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, CLEAR_FUNCT_MSG_LOOKUP_TABLE, None, None)

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, CLEAR_FUNCT_MSG_LOOKUP_TABLE, IntPtr.Zero, IntPtr.Zero);

ADD_TO_FUNCT_MSG_LOOKUP_TABLE — Dodanie adresu funkcjonalnego

Dodaje adres do tablicy adresów funkcjonalnych J1850. Komunikaty z tym adresem będą odbierane przy użyciu adresacji funkcjonalnej.

pInput SBYTE_ARRAY* — lista adresów do dodania
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
SBYTE_ARRAY AddrList;
unsigned char addresses[3] = {0x10, 0x18, 0x28};  // Adresy ECU
long ret;

AddrList.NumOfBytes = 3;
AddrList.BytePtr = addresses;

ret = PassThruIoctl(ChannelID, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Obsługa błędu
}

Przykład w Python

addresses = (c_ubyte * 3)(0x10, 0x18, 0x28)
addr_list = SBYTE_ARRAY()
addr_list.NumOfBytes = 3
addr_list.BytePtr = addresses

ret = j2534.PassThruIoctl(channel_id, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, byref(addr_list), None)

Przykład w C#

var addrList = new SBYTE_ARRAY {
    NumOfBytes = 3,
    BytePtr = new byte[] { 0x10, 0x18, 0x28 }
};
int ret = J2534.PassThruIoctl(channelId, ADD_TO_FUNCT_MSG_LOOKUP_TABLE, ref addrList, IntPtr.Zero);

DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE — Usunięcie adresu funkcjonalnego

Usuwa adres z tablicy adresów funkcjonalnych J1850.

pInput SBYTE_ARRAY* — lista adresów do usunięcia
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;
SBYTE_ARRAY AddrList;
unsigned char addresses[1] = {0x10};  // Adres do usunięcia
long ret;

AddrList.NumOfBytes = 1;
AddrList.BytePtr = addresses;

ret = PassThruIoctl(ChannelID, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, &AddrList, NULL);
if (ret != STATUS_NOERROR)
{
    // Obsługa błędu
}

Przykład w Python

addresses = (c_ubyte * 1)(0x10)
addr_list = SBYTE_ARRAY()
addr_list.NumOfBytes = 1
addr_list.BytePtr = addresses

ret = j2534.PassThruIoctl(channel_id, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, byref(addr_list), None)

Przykład w C#

var addrList = new SBYTE_ARRAY {
    NumOfBytes = 1,
    BytePtr = new byte[] { 0x10 }
};
int ret = J2534.PassThruIoctl(channelId, DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE, ref addrList, IntPtr.Zero);

SW_CAN_HS — Tryb wysokiej prędkości SW-CAN

Przełącza Single-Wire CAN w tryb wysokiej prędkości (83.3 kbit/s). Używany do diagnostyki z dużą prędkością w sieciach GM.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał SW-CAN
long ret;

// Przełączenie w tryb wysokiej prędkości
ret = PassThruIoctl(ChannelID, SW_CAN_HS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("SW-CAN w trybie High Speed (83.3 kbit/s)\n");
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, SW_CAN_HS, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "SW-CAN w trybie High Speed (83.3 kbit/s)")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, SW_CAN_HS, None, None)
if ret == 0:
    print("SW-CAN w trybie High Speed (83.3 kbit/s)")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, SW_CAN_HS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("SW-CAN w trybie High Speed (83.3 kbit/s)");

SW_CAN_NS — Tryb normalny SW-CAN

Przełącza Single-Wire CAN w tryb normalny (33.3 kbit/s). Jest to tryb domyślny dla sieci GM.

pInput NULL
pOutput NULL

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał SW-CAN
long ret;

// Przełączenie w tryb normalny
ret = PassThruIoctl(ChannelID, SW_CAN_NS, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("SW-CAN w trybie Normal Speed (33.3 kbit/s)\n");
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, SW_CAN_NS, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "SW-CAN w trybie Normal Speed (33.3 kbit/s)")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, SW_CAN_NS, None, None)
if ret == 0:
    print("SW-CAN w trybie Normal Speed (33.3 kbit/s)")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, SW_CAN_NS, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("SW-CAN w trybie Normal Speed (33.3 kbit/s)");

BUS_ON — Podłączenie kontrolera do magistrali v5.0

Podłącza kontroler CAN do magistrali fizycznej. Używane po odłączeniu kontrolera od magistrali przez PassThruDisconnect z flagą CAN_DISCONNECT lub po otwarciu kanału bez automatycznego podłączenia.

IoctlID 0x0F
pInput NULL
pOutput NULL
To polecenie jest dostępne tylko w J2534 v5.00. W v04.04 kontroler podłącza się do magistrali automatycznie przy PassThruConnect.

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał CAN
long ret;

// Podłączenie kontrolera do magistrali
ret = PassThruIoctl(ChannelID, BUS_ON, NULL, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Kontroler CAN podłączony do magistrali\n");
}

Przykład w Kotlin (Android)

val result = j2534.ptIoctl(channelID, BUS_ON, 0, null)
if (result.status == STATUS_NOERROR) {
    Log.i("J2534", "Kontroler CAN podłączony do magistrali")
}

Przykład w Python

ret = j2534.PassThruIoctl(channel_id, BUS_ON, None, None)
if ret == 0:
    print("Kontroler CAN podłączony do magistrali")

Przykład w C#

int ret = J2534.PassThruIoctl(channelId, BUS_ON, IntPtr.Zero, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("Kontroler CAN podłączony do magistrali");

REQUEST_CONNECTION — Nawiązanie połączenia TP 2.0 J2534-2

Żąda nawiązania kanału i połączenia TP 2.0 między adapterem a ECU. Używane dla protokołu TP 2.0 (VAG). Polecenie nieblokujące — wynik połączenia przychodzi jako wskazanie do kolejki odbiorczej.

IoctlID 0x800A
pInput SBYTE_ARRAY* — dane żądania połączenia (11 bajtów)
pOutput NULL

Struktura danych (11 bajtów)

BytePtr[0-3] CAN ID (identyfikator), BytePtr[0] — starszy bajt
BytePtr[4] Destination — adres docelowy (ECU)
BytePtr[5] Opcode — zawsze 0xC0
BytePtr[6-7] TX-ID-A — CAN ID do nadawania
BytePtr[8-9] RX-ID-A — CAN ID do odbioru
BytePtr[10] Application Type — typ aplikacji
Przy pomyślnym połączeniu tworzony jest niejawny filtr PASS dla RX-ID-A. Do kolejki odbiorczej trafia wskazanie CONNECTION_ESTABLISHED. Przy błędzie — CONNECTION_LOST.
Jeśli RX-ID-A jest już używany przez inny kanał, zwracany jest ERR_NOT_UNIQUE. Jeśli NumOfBytes ≠ 11, zwracany jest ERR_INVALID_IOCTL_VALUE.

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[11];
long ret;

// CAN ID dla broadcast: 0x200
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x02;
data[3] = 0x00;
// Destination (adres ECU, np. 0x01 dla silnika)
data[4] = 0x01;
// Opcode (zawsze 0xC0)
data[5] = 0xC0;
// TX-ID-A (CAN ID do nadawania, np. 0x300)
data[6] = 0x03;
data[7] = 0x00;
// RX-ID-A (CAN ID do odbioru, np. 0x301)
data[8] = 0x03;
data[9] = 0x01;
// Application Type (0x01 dla diagnostyki)
data[10] = 0x01;

InputData.NumOfBytes = 11;
InputData.BytePtr = data;

ret = PassThruIoctl(ChannelID, REQUEST_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED\n");
}
else if (ret == ERR_NOT_UNIQUE)
{
    printf("RX-ID-A jest już używany przez inny kanał\n");
}

Przykład w Kotlin (Android)

// channelID — kanał TP 2.0
val data = byteArrayOf(
    0x00, 0x00, 0x02, 0x00,  // CAN ID: 0x200
    0x01,                     // Destination: ECU 0x01
    0xC0.toByte(),            // Opcode
    0x03, 0x00,               // TX-ID-A: 0x300
    0x03, 0x01,               // RX-ID-A: 0x301
    0x01                      // Application Type
)

val result = j2534.ptIoctl(channelID, REQUEST_CONNECTION, data.size, data)
when (result.status) {
    STATUS_NOERROR -> Log.i("TP2.0", "Żądanie połączenia wysłane")
    ERR_NOT_UNIQUE -> Log.e("TP2.0", "RX-ID-A jest już używany")
    else -> Log.e("TP2.0", "Błąd: ${result.status}")
}

Przykład w Python

from ctypes import *

data = (c_ubyte * 11)(
    0x00, 0x00, 0x02, 0x00,  # CAN ID: 0x200
    0x01,                     # Destination: ECU 0x01
    0xC0,                     # Opcode
    0x03, 0x00,               # TX-ID-A: 0x300
    0x03, 0x01,               # RX-ID-A: 0x301
    0x01                      # Application Type
)

input_data = SBYTE_ARRAY()
input_data.NumOfBytes = 11
input_data.BytePtr = data

ret = j2534.PassThruIoctl(channel_id, REQUEST_CONNECTION, byref(input_data), None)
if ret == 0:
    print("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED")
elif ret == ERR_NOT_UNIQUE:
    print("RX-ID-A jest już używany przez inny kanał")

Przykład w C#

var data = new byte[] {
    0x00, 0x00, 0x02, 0x00,  // CAN ID: 0x200
    0x01,                     // Destination: ECU 0x01
    0xC0,                     // Opcode
    0x03, 0x00,               // TX-ID-A: 0x300
    0x03, 0x01,               // RX-ID-A: 0x301
    0x01                      // Application Type
};

var inputData = new SBYTE_ARRAY {
    NumOfBytes = 11,
    BytePtr = data
};

int ret = J2534.PassThruIoctl(channelId, REQUEST_CONNECTION, ref inputData, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("Żądanie połączenia wysłane, oczekujemy CONNECTION_ESTABLISHED");
else if (ret == ERR_NOT_UNIQUE)
    Console.WriteLine("RX-ID-A jest już używany przez inny kanał");

TEARDOWN_CONNECTION — Zerwanie połączenia TP 2.0 J2534-2

Zrywa nawiązane połączenie TP 2.0 między adapterem a ECU. Polecenie nieblokujące — potwierdzenie zerwania przychodzi jako wskazanie CONNECTION_LOST do kolejki odbiorczej.

IoctlID 0x800B
pInput SBYTE_ARRAY* — CAN ID odbioru (4 bajty)
pOutput NULL

Struktura danych (4 bajty)

BytePtr[0-3] RX-ID-A — CAN ID do odbioru (ten sam, co w REQUEST_CONNECTION), BytePtr[0] — starszy bajt
Po zerwaniu połączenia niejawny filtr PASS dla RX-ID-A jest usuwany. Filtry ustawione przez PassThruStartMsgFilter pozostają aktywne.

Przykład w C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID;  // Kanał TP 2.0
SBYTE_ARRAY InputData;
unsigned char data[4];
long ret;

// RX-ID-A (ten sam, co był w REQUEST_CONNECTION)
data[0] = 0x00;
data[1] = 0x00;
data[2] = 0x03;
data[3] = 0x01;  // 0x301

InputData.NumOfBytes = 4;
InputData.BytePtr = data;

ret = PassThruIoctl(ChannelID, TEARDOWN_CONNECTION, &InputData, NULL);
if (ret == STATUS_NOERROR)
{
    printf("Żądanie zerwania połączenia wysłane\n");
}

Przykład w Kotlin (Android)

// RX-ID-A: 0x301
val data = byteArrayOf(0x00, 0x00, 0x03, 0x01)

val result = j2534.ptIoctl(channelID, TEARDOWN_CONNECTION, data.size, data)
if (result.status == STATUS_NOERROR) {
    Log.i("TP2.0", "Żądanie zerwania połączenia wysłane")
}

Przykład w Python

from ctypes import *

# RX-ID-A: 0x301
data = (c_ubyte * 4)(0x00, 0x00, 0x03, 0x01)

input_data = SBYTE_ARRAY()
input_data.NumOfBytes = 4
input_data.BytePtr = data

ret = j2534.PassThruIoctl(channel_id, TEARDOWN_CONNECTION, byref(input_data), None)
if ret == 0:
    print("Żądanie zerwania połączenia wysłane")

Przykład w C#

// RX-ID-A: 0x301
var data = new byte[] { 0x00, 0x00, 0x03, 0x01 };

var inputData = new SBYTE_ARRAY {
    NumOfBytes = 4,
    BytePtr = data
};

int ret = J2534.PassThruIoctl(channelId, TEARDOWN_CONNECTION, ref inputData, IntPtr.Zero);
if (ret == 0)
    Console.WriteLine("Żądanie zerwania połączenia wysłane");