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 ChannelSetPtrChannelList 为 NULL
ERR_INVALID_CHANNEL_ID ChannelList 中的某个通道 ID 无效。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"

// 从 PassThruConnect/PassThruLogicalConnect 获取的通道 ID
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()}")

相关函数