-
首页
-
ScanDoc Development
- J2534 指南
-
PassThru 函数说明
- PassThruIoctl
GET_DEVICE_INFO / GET_PROTOCOL_INFO J2534-2
设备信息
最后修改:
GET_DEVICE_INFO — 设备信息
返回设备能力信息:所支持的协议、可同时打开的通道数量、序列号及其他特性。调用时使用从 PassThruOpen 获取的 DeviceID。
| IoctlID |
0x800C |
| pInput |
SCONFIG_LIST* — 所请求参数的列表 |
| pOutput |
NULL(结果写入 pInput) |
与 GET_CONFIG 不同,GET_DEVICE_INFO 函数调用时使用 DeviceID,而非 ChannelID。
GET_PROTOCOL_INFO — 协议信息
返回特定协议的能力信息:最大缓冲区大小、过滤器数量、所支持的参数。调用时使用从 PassThruConnect 获取的 ChannelID。
| IoctlID |
0x800D |
| pInput |
SCONFIG_LIST* — 所请求参数的列表 |
| pOutput |
NULL(结果写入 pInput) |
数据结构
typedef struct {
unsigned long Parameter; // 参数标识符
unsigned long Value; // 返回值
} SCONFIG;
typedef struct {
unsigned long NumOfParams; // 列表中的参数数量
SCONFIG *ConfigPtr; // 指向 SCONFIG 数组的指针
} SCONFIG_LIST;
返回的错误代码
| 代码 |
说明 |
可能原因及解决方法 |
| STATUS_NOERROR |
函数执行成功 |
— |
| ERR_DEVICE_NOT_CONNECTED |
未与适配器建立连接 |
- 适配器已关闭或不在通信范围内
- 解决方法:检查供电和连接
|
| ERR_INVALID_DEVICE_ID |
无效的设备标识符 |
- DeviceID 未通过 PassThruOpen 获取
- 解决方法:执行 PassThruOpen
|
| ERR_INVALID_CHANNEL_ID |
无效的通道标识符 |
- ChannelID 未通过 PassThruConnect 获取(用于 GET_PROTOCOL_INFO)
- 解决方法:执行 PassThruConnect
|
| ERR_NULL_PARAMETER |
传入了 NULL 而非指针 |
- pInput 为 NULL
- 解决方法:传入指向 SCONFIG_LIST 的指针
|
| ERR_NOT_SUPPORTED |
参数不受支持 |
- 所请求的参数不可用
- 解决方法:检查所支持的参数列表
|
| ERR_FAILED |
未定义的错误 |
- 内部错误
- 解决方法:调用
PassThruGetLastError()
|
GET_DEVICE_INFO 参数
设备标识
| 参数 |
值 |
说明 |
| SERIAL_NUMBER |
0x01 |
设备序列号(字符串) |
| PART_NUMBER |
0x49 |
设备物料编号 |
协议支持
返回 SUPPORTED(1)或 NOT_SUPPORTED(0)。
| 参数 |
值 |
协议 |
| J1850PWM_SUPPORTED |
0x02 |
J1850 PWM (Ford) |
| J1850VPW_SUPPORTED |
0x03 |
J1850 VPW (GM) |
| ISO9141_SUPPORTED |
0x04 |
ISO 9141-2 |
| ISO14230_SUPPORTED |
0x05 |
ISO 14230 (KWP2000) |
| CAN_SUPPORTED |
0x06 |
CAN (raw) |
| ISO15765_SUPPORTED |
0x07 |
ISO 15765 (CAN UDS) |
| SCI_A_ENGINE_SUPPORTED |
0x08 |
SCI-A Engine (Chrysler) |
| SCI_A_TRANS_SUPPORTED |
0x09 |
SCI-A Transmission (Chrysler) |
| SCI_B_ENGINE_SUPPORTED |
0x0A |
SCI-B Engine (Chrysler) |
| SCI_B_TRANS_SUPPORTED |
0x0B |
SCI-B Transmission (Chrysler) |
| SW_ISO15765_SUPPORTED |
0x0C |
Single-Wire ISO 15765 |
| SW_CAN_SUPPORTED |
0x0D |
Single-Wire CAN (GM) |
| GM_UART_SUPPORTED |
0x0E |
GM UART |
| UART_ECHO_BYTE_SUPPORTED |
0x0F |
UART Echo Byte |
| HONDA_DIAGH_SUPPORTED |
0x10 |
Honda DIAG-H |
| J1939_SUPPORTED |
0x11 |
J1939(商用车) |
| J1708_SUPPORTED |
0x12 |
J1708(商用车) |
| TP2_0_SUPPORTED |
0x13 |
TP 2.0 (VAG) |
| J2610_SUPPORTED |
0x14 |
J2610 (Chrysler DRB-III) |
| ANALOG_IN_SUPPORTED |
0x15 |
模拟输入 |
| FT_CAN_SUPPORTED |
0x31 |
Fault-Tolerant CAN |
| FT_ISO15765_SUPPORTED |
0x32 |
FT ISO 15765 |
| FD_CAN_SUPPORTED |
0x4C |
CAN FD |
| FD_ISO15765_SUPPORTED |
0x4D |
通过 CAN FD 的 ISO 15765 |
| ETHERNET_NDIS_SUPPORTED |
0x54 |
Ethernet NDIS (DoIP) |
同时打开的通道
每种协议可同时打开的通道数量。
| 参数 |
值 |
协议 |
| J1850PWM_SIMULTANEOUS |
0x35 |
J1850 PWM |
| J1850VPW_SIMULTANEOUS |
0x36 |
J1850 VPW |
| ISO9141_SIMULTANEOUS |
0x37 |
ISO 9141 |
| ISO14230_SIMULTANEOUS |
0x38 |
ISO 14230 |
| CAN_SIMULTANEOUS |
0x39 |
CAN |
| ISO15765_SIMULTANEOUS |
0x3A |
ISO 15765 |
| SW_CAN_SIMULTANEOUS |
0x40 |
SW-CAN |
| J1939_SIMULTANEOUS |
0x44 |
J1939 |
| TP2_0_SIMULTANEOUS |
0x46 |
TP 2.0 |
| FD_CAN_SIMULTANEOUS |
0x4E |
CAN FD |
| FD_ISO15765_SIMULTANEOUS |
0x4F |
ISO 15765 FD |
J1962 引脚分配
返回协议所使用的 OBD-II 引脚掩码。
| 参数 |
值 |
协议 |
| CAN_PS_J1962 |
0x1F |
CAN (Pin 6, 14) |
| ISO15765_PS_J1962 |
0x20 |
ISO 15765 (Pin 6, 14) |
| ISO9141_PS_K_LINE_J1962 |
0x1B |
ISO 9141 K-Line (Pin 7) |
| ISO9141_PS_L_LINE_J1962 |
0x1C |
ISO 9141 L-Line (Pin 15) |
| ISO14230_PS_K_LINE_J1962 |
0x1D |
ISO 14230 K-Line (Pin 7) |
| ISO14230_PS_L_LINE_J1962 |
0x1E |
ISO 14230 L-Line (Pin 15) |
| SW_CAN_PS_J1962 |
0x21 |
SW-CAN (Pin 1) |
| J1850PWM_PS_J1962 |
0x19 |
J1850 PWM (Pin 2, 10) |
| J1850VPW_PS_J1962 |
0x1A |
J1850 VPW (Pin 2) |
| FD_CAN_PS_J1962 |
0x50 |
CAN FD (Pin 6, 14) |
| FD_ISO15765_PS_J1962 |
0x51 |
ISO 15765 FD (Pin 6, 14) |
其他能力
| 参数 |
值 |
说明 |
| MAX_NON_VOLATILE_STORAGE |
0x16 |
非易失性存储器大小(字节) |
| SHORT_TO_GND_J1962 |
0x17 |
支持检测对地短路 |
| PGM_VOLTAGE_J1962 |
0x18 |
支持编程电压 |
| READ_J1962PIN_VOLTAGE_SUPPORTED |
0x52 |
支持读取引脚电压 |
| READ_J1962PIN_VOLTAGE_MAX |
0x53 |
可读取的最大电压(mV) |
GET_PROTOCOL_INFO 参数
| 参数 |
值 |
说明 |
| MAX_RX_BUFFER_SIZE |
0x01 |
接收缓冲区最大大小(字节) |
| MAX_PASS_FILTER |
0x02 |
PASS_FILTER 的最大数量 |
| MAX_BLOCK_FILTER |
0x03 |
BLOCK_FILTER 的最大数量 |
| MAX_FILTER_MSG_LENGTH |
0x04 |
过滤器消息的最大长度(字节) |
| MAX_PERIODIC_MSGS |
0x05 |
周期性消息的最大数量 |
| MAX_PERIODIC_MSG_LENGTH |
0x06 |
周期性消息的最大长度(字节) |
| DESIRED_DATA_RATE |
0x07 |
推荐的传输速率(位/秒) |
| MAX_FLOW_CONTROL_FILTER |
0x12 |
FLOW_CONTROL_FILTER 的最大数量 |
| MAX_ISO15765_WFT_MAX |
0x13 |
ISO15765_WFT_MAX 的最大值 |
| NETWORK_LINE_SUPPORTED |
0x0A |
支持选择网络线路 |
| MAX_FUNCT_MSG_LOOKUP |
0x0B |
功能地址表的最大大小 |
| PARITY_SUPPORTED |
0x0C |
支持奇偶校验配置 |
| DATA_BITS_SUPPORTED |
0x0D |
支持数据位配置(7/8) |
| FIVE_BAUD_MOD_SUPPORTED |
0x0E |
支持 5 波特初始化模式 |
| L_LINE_SUPPORTED |
0x0F |
支持 L-Line |
| CAN_11_29_IDS_SUPPORTED |
0x10 |
支持 11 位和 29 位 CAN ID |
| CAN_MIXED_FORMAT_SUPPORTED |
0x11 |
支持 CAN 混合格式 |
| TIMESTAMP_RESOLUTION |
0x1B |
时间戳分辨率(μs) |
| FD_CAN_DATA_PHASE_DATA_RATE_SUPPORTED |
0x6C |
所支持的 CAN FD 速率 |
示例
GET_DEVICE_INFO — 获取设备能力
C/C++ 示例
#include "j2534_dll.hpp"
unsigned long DeviceID; // 从 PassThruOpen 获取
SCONFIG Config[5];
SCONFIG_LIST ConfigList;
long ret;
// 查询协议支持信息
Config[0].Parameter = CAN_SUPPORTED;
Config[1].Parameter = ISO15765_SUPPORTED;
Config[2].Parameter = ISO14230_SUPPORTED;
Config[3].Parameter = FD_CAN_SUPPORTED;
Config[4].Parameter = TP2_0_SUPPORTED;
ConfigList.NumOfParams = 5;
ConfigList.ConfigPtr = Config;
ret = PassThruIoctl(DeviceID, GET_DEVICE_INFO, &ConfigList, NULL);
if (ret == STATUS_NOERROR)
{
printf("CAN: %s\n", Config[0].Value ? "支持" : "否");
printf("ISO 15765: %s\n", Config[1].Value ? "支持" : "否");
printf("ISO 14230: %s\n", Config[2].Value ? "支持" : "否");
printf("CAN FD: %s\n", Config[3].Value ? "支持" : "否");
printf("TP 2.0: %s\n", Config[4].Value ? "支持" : "否");
}
Kotlin (Android) 示例
// deviceID 从 ptOpen 获取
val params = listOf(
PtConfig(parameter = CAN_SUPPORTED, value = 0u),
PtConfig(parameter = ISO15765_SUPPORTED, value = 0u),
PtConfig(parameter = FD_CAN_SUPPORTED, value = 0u)
)
val result = j2534.ptIoctl(deviceID, GET_DEVICE_INFO, params.size, params.toByteArray())
if (result.status == STATUS_NOERROR) {
val resultParams = result.toConfigList()
Log.i("J2534", "CAN: ${if (resultParams[0].value > 0u) "是" else "否"}")
Log.i("J2534", "ISO 15765: ${if (resultParams[1].value > 0u) "是" else "否"}")
Log.i("J2534", "CAN FD: ${if (resultParams[2].value > 0u) "是" else "否"}")
}
Python 示例
from ctypes import *
config = (SCONFIG * 3)()
config[0].Parameter = CAN_SUPPORTED
config[1].Parameter = ISO15765_SUPPORTED
config[2].Parameter = FD_CAN_SUPPORTED
config_list = SCONFIG_LIST()
config_list.NumOfParams = 3
config_list.ConfigPtr = config
ret = j2534.PassThruIoctl(device_id, GET_DEVICE_INFO, byref(config_list), None)
if ret == 0:
print(f"CAN: {'是' if config[0].Value else '否'}")
print(f"ISO 15765: {'是' if config[1].Value else '否'}")
print(f"CAN FD: {'是' if config[2].Value else '否'}")
C# 示例
var configs = new SCONFIG[3];
configs[0].Parameter = CAN_SUPPORTED;
configs[1].Parameter = ISO15765_SUPPORTED;
configs[2].Parameter = FD_CAN_SUPPORTED;
var configList = new SCONFIG_LIST {
NumOfParams = 3,
ConfigPtr = configs
};
int ret = J2534.PassThruIoctl(deviceId, GET_DEVICE_INFO, ref configList, IntPtr.Zero);
if (ret == 0)
{
Console.WriteLine($"CAN: {(configs[0].Value > 0 ? "是" : "否")}");
Console.WriteLine($"ISO 15765: {(configs[1].Value > 0 ? "是" : "否")}");
Console.WriteLine($"CAN FD: {(configs[2].Value > 0 ? "是" : "否")}");
}
GET_PROTOCOL_INFO — 获取协议信息
C/C++ 示例
#include "j2534_dll.hpp"
unsigned long ChannelID; // 从 PassThruConnect 获取,用于 ISO15765
SCONFIG Config[4];
SCONFIG_LIST ConfigList;
long ret;
// 查询协议限制
Config[0].Parameter = MAX_RX_BUFFER_SIZE;
Config[1].Parameter = MAX_FLOW_CONTROL_FILTER;
Config[2].Parameter = MAX_PERIODIC_MSGS;
Config[3].Parameter = TIMESTAMP_RESOLUTION;
ConfigList.NumOfParams = 4;
ConfigList.ConfigPtr = Config;
ret = PassThruIoctl(ChannelID, GET_PROTOCOL_INFO, &ConfigList, NULL);
if (ret == STATUS_NOERROR)
{
printf("最大 RX 缓冲区大小: %lu 字节\n", Config[0].Value);
printf("最大 FLOW_CONTROL 过滤器数: %lu\n", Config[1].Value);
printf("最大周期性消息数: %lu\n", Config[2].Value);
printf("timestamp 分辨率: %lu 微秒\n", Config[3].Value);
}
Kotlin (Android) 示例
// channelID 从 ptConnect 获取
val params = listOf(
PtConfig(parameter = MAX_RX_BUFFER_SIZE, value = 0u),
PtConfig(parameter = MAX_FLOW_CONTROL_FILTER, value = 0u),
PtConfig(parameter = MAX_PERIODIC_MSGS, value = 0u)
)
val result = j2534.ptIoctl(channelID, GET_PROTOCOL_INFO, params.size, params.toByteArray())
if (result.status == STATUS_NOERROR) {
val resultParams = result.toConfigList()
Log.i("J2534", "最大 RX 缓冲区: ${resultParams[0].value} 字节")
Log.i("J2534", "最大 FC 过滤器数: ${resultParams[1].value}")
Log.i("J2534", "最大周期性消息数: ${resultParams[2].value}")
}
Python 示例
from ctypes import *
config = (SCONFIG * 3)()
config[0].Parameter = MAX_RX_BUFFER_SIZE
config[1].Parameter = MAX_FLOW_CONTROL_FILTER
config[2].Parameter = MAX_PERIODIC_MSGS
config_list = SCONFIG_LIST()
config_list.NumOfParams = 3
config_list.ConfigPtr = config
ret = j2534.PassThruIoctl(channel_id, GET_PROTOCOL_INFO, byref(config_list), None)
if ret == 0:
print(f"最大 RX 缓冲区: {config[0].Value} 字节")
print(f"最大 FC 过滤器数: {config[1].Value}")
print(f"最大周期性消息数: {config[2].Value}")
设备能力完整检查
C/C++ 示例
#include "j2534_dll.hpp"
#include <stdio.h>
void PrintDeviceCapabilities(unsigned long DeviceID)
{
// 要检查的所有协议列表
struct {
unsigned long param;
const char* name;
} protocols[] = {
{CAN_SUPPORTED, "CAN"},
{ISO15765_SUPPORTED, "ISO 15765"},
{ISO14230_SUPPORTED, "ISO 14230 (KWP2000)"},
{ISO9141_SUPPORTED, "ISO 9141"},
{J1850PWM_SUPPORTED, "J1850 PWM"},
{J1850VPW_SUPPORTED, "J1850 VPW"},
{FD_CAN_SUPPORTED, "CAN FD"},
{FD_ISO15765_SUPPORTED, "ISO 15765 FD"},
{TP2_0_SUPPORTED, "TP 2.0 (VAG)"},
{J1939_SUPPORTED, "J1939"},
{SW_CAN_SUPPORTED, "Single-Wire CAN"}
};
const int count = sizeof(protocols) / sizeof(protocols[0]);
SCONFIG* config = new SCONFIG[count];
SCONFIG_LIST configList;
for (int i = 0; i < count; i++) {
config[i].Parameter = protocols[i].param;
config[i].Value = 0;
}
configList.NumOfParams = count;
configList.ConfigPtr = config;
long ret = PassThruIoctl(DeviceID, GET_DEVICE_INFO, &configList, NULL);
if (ret == STATUS_NOERROR) {
printf("=== 支持的协议 ===\n");
for (int i = 0; i < count; i++) {
printf("%-20s: %s\n", protocols[i].name,
config[i].Value ? "是" : "否");
}
}
delete[] config;
}