Quantex GmbH
您的地区:欧洲

PassThruStartMsgFilter v4.04 v5.0

设置消息过滤器

最后修改:

说明

在开始接收或发送消息之前,必须设置消息过滤器。如果未设置任何过滤器,则所有消息都会被阻止。对于 ISO 15765 协议,仅可使用一种过滤器类型 FLOW_CONTROL_FILTER。该过滤器不能 用于其他协议。每个 ChannelID 最多可创建 16 个 FLOW_CONTROL_FILTER 以及最多 10 个 PASS_FILTER 或 BLOCK_FILTER。对于所选的每种过滤器类型,都必须指定过滤器参数。对于 FLOW_CONTROL_FILTER,需指定 三个参数 pMaskMsg、pPatternMsg、pFlowControlMsg。对于 PASS_FILTER 或 BLOCK_FILTER,需指定两个参数 pMaskMsg 和 pPatternMsg。参数长度可为 1 到 12 字节。

long PassThruStartMsgFilter(unsigned long ChannelID, unsigned long FilterType, PASSTHRU_MSG *pMaskMsg, PASSTHRU_MSG *pPatternMsg, PASSTHRU_MSG *pFlowControlMsg, unsigned long *FilterID)

参数

在 ISO 15765 协议中存在标准消息和扩展消息。标准消息的报头使用 4 个字节,扩展消息使用 5 个字节。扩展报头例如用于 Toyota 的 BCM 或 BMW 的 ECU 中。

返回的错误代码

代码 说明 可能的原因及解决方法
STATUS_NOERROR 函数执行成功
ERR_DEVICE_NOT_CONNECTED 未与适配器建立连接
  • 适配器已关闭或不在可访问范围内
  • 解决方法:检查适配器供电及网络连接
ERR_INVALID_DEVICE_ID 无效的设备标识符
  • DeviceID 未通过 PassThruOpen 获取,或设备已关闭
  • 解决方法:确认 PassThruOpen 已成功执行
ERR_INVALID_CHANNEL_ID 无效的通道标识符
  • ChannelID 未通过 PassThruConnect 获取,或通道已关闭
  • 解决方法:确认 PassThruConnect 已成功执行
ERR_INVALID_MSG 消息结构不正确
  • pMaskMsg、pPatternMsg 或 pFlowControlMsg 中的结构不正确
  • 各消息的 TxFlags 或 DataSize 不一致
  • 解决方法:检查所有消息中 ProtocolID、DataSize 和 TxFlags 字段的正确性
ERR_NULL_PARAMETER 传入了 NULL 而非必需的指针
  • pMaskMsg、pPatternMsg 或 FilterID 等于 NULL
  • 解决方法:传入正确的结构指针
ERR_NOT_UNIQUE CAN ID 已在另一个 FLOW_CONTROL_FILTER 中使用
  • pPatternMsg 或 pFlowControlMsg 中的 CAN ID 与现有过滤器中的 ID 重复
  • 解决方法:删除现有过滤器或使用其他 CAN ID
ERR_EXCEEDED_LIMIT 超出过滤器数量上限
  • 已达上限:每个通道 16 个 FLOW_CONTROL_FILTER 或 10 个 PASS/BLOCK_FILTER
  • 解决方法:通过 PassThruStopMsgFilter 删除未使用的过滤器
ERR_MSG_PROTOCOL_ID 协议不匹配
  • 过滤器消息中的 ProtocolID 与通道协议不一致
  • 解决方法:使用与 PassThruConnect 中所指定相同的 ProtocolID
ERR_FAILED 未定义的错误
  • 库或适配器的内部错误
  • 解决方法:调用 PassThruGetLastError() 以获取详细说明

示例

ISO15765 (CAN) 协议

C/C++ 示例

#include "j2534_lib.hpp"

// ... ChannelID 从 PassThruConnect 获取 ...

PASSTHRU_MSG MaskMsg, PatternMsg, FlowControlMsg;
unsigned long FilterID;
long Ret;

// 掩码:比较前 4 个字节(CAN ID)
MaskMsg.ProtocolID = ISO15765;
MaskMsg.DataSize = 4;
memset(MaskMsg.Data, 0xFF, 4);

// 模板:接收 CAN ID 为 0x7E8 的消息
PatternMsg.ProtocolID = ISO15765;
PatternMsg.DataSize = 4;
PatternMsg.Data[0] = 0x00;
PatternMsg.Data[1] = 0x00;
PatternMsg.Data[2] = 0x07;
PatternMsg.Data[3] = 0xE8;

// FlowControl 响应:发送到 CAN ID 0x7E0
FlowControlMsg.ProtocolID = ISO15765;
FlowControlMsg.DataSize = 4;
FlowControlMsg.Data[0] = 0x00;
FlowControlMsg.Data[1] = 0x00;
FlowControlMsg.Data[2] = 0x07;
FlowControlMsg.Data[3] = 0xE0;

Ret = PassThruStartMsgFilter(ChannelID, FLOW_CONTROL_FILTER,
                             &MaskMsg, &PatternMsg, &FlowControlMsg, &FilterID);
if (Ret != STATUS_NOERROR)
{
    // 错误处理
}

Kotlin (Android) 示例

// channelID 此前从 ptConnect 获取
val mask = PassThruMsg(
    protocolID = ISO15765,
    dataSize = 4,
    txFlags = ISO15765_FRAME_PAD,
    // CAN ID 的掩码(比较全部 4 个字节)
    data = byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())
)
val pattern = PassThruMsg(
    protocolID = ISO15765,
    dataSize = 4,
    txFlags = ISO15765_FRAME_PAD,
    // 接收来自 CAN ID 为 0x7E8 的 ECU 的响应
    data = byteArrayOf(0x00, 0x00, 0x07, 0xE8.toByte())
)
val flowControl = PassThruMsg(
    protocolID = ISO15765,
    dataSize = 4,
    txFlags = ISO15765_FRAME_PAD,
    // 将 FlowControl 发送到 CAN ID 0x7E0
    data = byteArrayOf(0x00, 0x00, 0x07, 0xE0.toByte())
)

val resFilter = j2534.ptStartMsgFilter(channelID, FLOW_CONTROL_FILTER, mask, pattern, flowControl)
if (resFilter.status == STATUS_NOERROR) {
    val filterID = resFilter.filterId
    // 过滤器设置成功
    Log.i("J2534", "已设置 FLOW_CONTROL_FILTER 过滤器,ID: $filterID")
} else {
    // 错误处理
    Log.e("J2534", "设置过滤器出错: ${resFilter.status}")
}

Python 示例

from ctypes import *

# channelID 此前从 PassThruConnect 获取

# 创建消息结构
mask = PASSTHRU_MSG()
mask.ProtocolID = ISO15765
mask.DataSize = 4
mask.Data[0:4] = [0xFF, 0xFF, 0xFF, 0xFF]

pattern = PASSTHRU_MSG()
pattern.ProtocolID = ISO15765
pattern.DataSize = 4
pattern.Data[0:4] = [0x00, 0x00, 0x07, 0xE8]

flow_control = PASSTHRU_MSG()
flow_control.ProtocolID = ISO15765
flow_control.DataSize = 4
flow_control.Data[0:4] = [0x00, 0x00, 0x07, 0xE0]

filter_id = c_ulong()
ret = j2534.PassThruStartMsgFilter(
    channel_id, FLOW_CONTROL_FILTER,
    byref(mask), byref(pattern), byref(flow_control), byref(filter_id)
)
if ret == 0:  # STATUS_NOERROR
    print(f"过滤器已设置,ID: {filter_id.value}")
else:
    print(f"错误: {ret}")

C# 示例

// channelID 此前从 PassThruConnect 获取

var mask = new PASSTHRU_MSG {
    ProtocolID = ISO15765,
    DataSize = 4,
    Data = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }
};

var pattern = new PASSTHRU_MSG {
    ProtocolID = ISO15765,
    DataSize = 4,
    Data = new byte[] { 0x00, 0x00, 0x07, 0xE8 }
};

var flowControl = new PASSTHRU_MSG {
    ProtocolID = ISO15765,
    DataSize = 4,
    Data = new byte[] { 0x00, 0x00, 0x07, 0xE0 }
};

uint filterId;
int ret = J2534.PassThruStartMsgFilter(
    channelId, FLOW_CONTROL_FILTER,
    ref mask, ref pattern, ref flowControl, out filterId
);
if (ret == 0) // STATUS_NOERROR
{
    Console.WriteLine($"过滤器已设置,ID: {filterId}");
}

ISO14230 (K-Line) 协议

C/C++ 示例

#include "j2534_lib.hpp"

// ... ChannelID 从 PassThruConnect 获取 ...

PASSTHRU_MSG MaskMsg, PatternMsg;
unsigned long FilterID;
long Ret;

// 掩码:比较第一个字节(格式)
MaskMsg.ProtocolID = ISO14230;
MaskMsg.DataSize = 1;
MaskMsg.Data[0] = 0x80;

// 模板:放行所有格式位 = 1 的消息
PatternMsg.ProtocolID = ISO14230;
PatternMsg.DataSize = 1;
PatternMsg.Data[0] = 0x80;

Ret = PassThruStartMsgFilter(ChannelID, PASS_FILTER, &MaskMsg, &PatternMsg, NULL, &FilterID);
if (Ret != STATUS_NOERROR)
{
    // 错误处理
}