Python如何解析含CAN-TP帧的.asc/.blf格式CAN日志文件?
针对含CAN-TP帧的.asc格式CAN日志解析的Python方案
有成熟的Python库可直接完成该需求,无需从零开发日志解析和CAN-TP拼接逻辑:
- 日志解析用
python-can库:原生支持Vector .asc格式日志读取,可直接提取每帧的时间戳、通道号、仲裁ID、收发方向、载荷等核心字段,无需手动处理日志文本格式。 - CAN-TP(ISO 15765-2)帧拼接用
cantools内置的isotp模块:内置完整的单帧、首帧、流控帧、连续帧处理逻辑,可自动按「ID+收发方向」分组拼接多帧载荷,自动处理超时、流控参数等协议规则。
实现步骤
1. 安装依赖
pip install python-can cantools
2. 示例代码
import can from cantools.isotp import StateMachine, Message # 存储不同ID+方向的ISO-TP会话状态机,key格式为(仲裁ID, 是否为发送帧) isotp_sessions = {} with open("你的日志文件路径.asc", "r", encoding="latin-1") as f: reader = can.io.AscReader(f) for msg in reader: if not msg.data: continue session_key = (msg.arbitration_id, msg.is_tx) payload_hex = " ".join([f"{b:02X}" for b in msg.data]) # 判断是否为CAN-TP帧:首字节高4位为0(单帧)/1(首帧)/2(连续帧)/3(流控帧) tp_n_pci = msg.data[0] >> 4 if tp_n_pci not in [0, 1, 2, 3]: # 非CAN-TP普通帧直接输出 print(f"{msg.timestamp:.6f} CAN {msg.channel+1} {msg.arbitration_id:<20} CAN Frame {'Tx' if msg.is_tx else 'Rx'} {msg.dlc} {msg.dlc} {payload_hex}") continue # CAN-TP帧拼接逻辑 if session_key not in isotp_sessions: isotp_sessions[session_key] = StateMachine(timeout=1.0) # 记录首帧时间戳用于输出 isotp_sessions[session_key].first_ts = msg.timestamp sm = isotp_sessions[session_key] # 送入当前帧处理 out_msg = sm.process_message(Message(msg.arbitration_id, msg.data, msg.is_extended_id)) # 拼接完成后输出完整帧 if out_msg is not None: full_payload_hex = " ".join([f"{b:02X}" for b in out_msg.data]) print(f"{sm.first_ts:.6f} CAN {msg.channel+1} {msg.arbitration_id:<20} CAN Frame {'Tx' if msg.is_tx else 'Rx'} {len(out_msg.data)} {len(out_msg.data)} {full_payload_hex}") # 清空已完成的会话 del isotp_sessions[session_key]
上述代码会自动区分普通CAN帧和CAN-TP帧,普通帧直接输出,CAN-TP多帧全部接收完成后拼接为完整载荷输出,完全匹配你要求的输出格式,可根据需求调整超时时间、输出字段、扩展帧支持等参数。
内容的提问来源于stack exchange,提问作者Lyes kheffache
相关产品推荐
相关产品推荐

