网易首页 > 网易号 > 正文 申请入驻

CAN 诊断浅谈:从协议到 C++ 实现与工具实践

0
分享至


车载诊断早已不是简单“读个故障码”那么简单。从产线下线检测、售后维修,到 ECU 刷写、功能标定,诊断贯穿了汽车电子的全生命周期。理解 CAN 诊断,核心在于理清传输层(ISO-TP)与应用层(UDS)的协作关系。下面从协议框架切入,给出可运行的 C++ 代码思路,并说明如何借助专业工具完成实际诊断任务。

一、CAN 诊断的协议栈:两层各司其职

CAN 总线单帧数据场最多 8 字节,而一条诊断请求或响应(例如带数据的正响应、故障码列表)动辄几十甚至上千字节。这就需要一个“中间人”来切分和重组数据。

ISO-TP(ISO 15765-2)正是这个中间人。它定义了四种帧类型:

帧类型

简称

作用

单帧

SF

数据长度 ≤ 7 字节时,一帧发完

首帧

FF

数据较长时,第一帧携带总长度与开头数据

连续帧

CF

后续携带剩余数据,带序列号防错序

流控帧

FC

接收方告诉发送方“继续发 / 暂停 / 缓冲满了”

UDS(ISO 14229-1)则定义在应用层,负责“说什么”。它规定了诊断服务的请求与响应格式,例如0x22读数据、0x2E写数据、0x19读故障码、0x27安全访问等。ISO-TP 负责搬运,UDS 负责语义。

诊断的典型交互是请求—响应模式:诊断仪(Tester)发送请求,ECU 要么回复正响应(SID+0x40),要么回复否定响应(0x7F+ 原SID + NRC 码)。

二、C++ 代码示例:从零封装一条 UDS 请求

直接用原生 CAN 驱动发 UDS 请求,需要自己处理 ISO-TP 的分帧、流控、超时。下面用伪代码风格展示核心逻辑,便于理解底层的“手工活”。

假设你使用 SocketCAN(Linux 下常见)或 PCAN 的 CAN 发送接口。

2.1 发送单帧请求(例如读 DID0xF190

#include  

#include
#include
#include

// 假设 sock 已初始化,CAN ID 为 0x7DF(功能寻址)或 0x7E0(物理寻址)
int send_uds_single_frame(int sock, canid_t tx_id, uint8_t sid, uint8_t did_high, uint8_t did_low) {
struct can_frame frame;
memset(&frame, 0, sizeof(frame));
frame.can_id = tx_id;
frame.can_dlc = 8;

// ISO-TP 单帧格式:高4位=0(单帧),低4位=数据长度(3字节)
frame.data[0] = 0x03; // SF, 长度为3
frame.data[1] = sid; // 服务ID,例如 0x22
frame.data[2] = did_high; // DID 高位
frame.data[3] = did_low; // DID 低位
// data[4..7] 为填充字节(通常 0xCC 或 0x00)
frame.data[4] = 0xCC;
frame.data[5] = 0xCC;
frame.data[6] = 0xCC;
frame.data[7] = 0xCC;

int nbytes = write(sock, &frame, sizeof(frame));
if (nbytes != sizeof(frame)) {
std::cerr << "发送失败" << std::endl;
return -1;
}
return 0;
}

调用方式:send_uds_single_frame(sock, 0x7E0, 0x22, 0xF1, 0x90)。

2.2 多帧接收的流控逻辑(简化示意)

当 ECU 返回的响应超过 7 字节时,会先发首帧(FF),此时 Tester 需要回一条流控帧(FC)告诉 ECU “继续发,每包间隔 X 毫秒”。

// 收到 ECU 的响应首帧后,发送流控帧
void send_flow_control(int sock, canid_t tx_id) {
struct can_frame fc;
memset(&fc, 0, sizeof(fc));
fc.can_id = tx_id;
fc.can_dlc = 8;

// FC 格式:高4位=3(流控),低4位=流状态(0=继续)
fc.data[0] = 0x30; // 0x3 表示 FC,0x0 表示 CTS(继续发送)
fc.data[1] = 0x00; // Block Size = 0(无限制)
fc.data[2] = 0x14; // STmin = 20ms(0x14 是 ISO-TP 时间参数编码)
// 后续填充
fc.data[3] = 0xAA;
fc.data[4] = 0xAA;
fc.data[5] = 0xAA;
fc.data[6] = 0xAA;
fc.data[7] = 0xAA;

write(sock, &fc, sizeof(fc));
}

ECU 收到 FC 后,就会用连续帧(CF)把剩余数据发完,Tester 再按序列号拼装即可。

三、实际开发中更推荐的做法:使用成熟的 UDS 库

手写 ISO-TP 容易在超时、序列号错误、NRC 处理上踩坑。实际项目中通常使用现成的库,例如PCAN-UDS API或开源 C++ 实现。

以 PCAN-UDS 发送一条“清除故障码”请求为例,API 封装了所有传输层细节:

TPUDSMsg request, response, requestConfirmation;
TPUDSStatus result;

// 配置网络地址信息
request.NETADDRINFO.SA = PUDS_ISO_15765_4_ADDR_TEST_EQUIPMENT; // 0xF1
request.NETADDRINFO.TA = PUDS_ISO_15765_4_ADDR_ECU_1; // 0x01
request.NETADDRINFO.TA_TYPE = PUDS_ADDRESSING_PHYSICAL;
request.NETADDRINFO.PROTOCOL = PUDS_PROTOCOL_ISO_15765_2_11B;

// 发送 ClearDiagnosticInformation(0x14),清除所有 DTC
result = UDS_SvcClearDiagnosticInformation(PUDS_USBBUS1, &request, 0xFFFFFF);
if (result == PUDS_ERROR_OK) {
// 等待 ECU 响应,库内部自动处理流控和重组
result = UDS_WaitForService(PUDS_USBBUS1, &response, &request, &requestConfirmation);
}
// 检查 response 中是否为正响应 0x54

这样代码聚焦于业务逻辑(发什么服务、带什么参数),而不必纠缠于帧切分。

四、如何用 CAN 工具进行诊断:以 CANoe 为例

CANoe/CANalyzer 是行业主流诊断工具,其诊断功能围绕CDD 文件(CANdela Diagnostic Description)展开。

4.1 配置阶段

在Diagnostics / ISO-TP Configuration窗口中导入 CDD 文件。CDD 文件由 OEM 或 ECU 供应商提供,里面描述了该 ECU 支持哪些 UDS 服务、每个服务需要什么参数、DID 的含义、DTC 的定义等。

导入 CDD 后,CANoe 会自动弹出Fault Memory和Session Control窗口,前者用于读写 DTC,后者用于切换诊断会话(Default / Extended / Programming)和安全等级。

4.2 手动发送诊断请求

在Diagnostic Console窗口中,左侧会列出 CDD 中定义的所有服务。双击某个服务,右侧会生成请求报文,填写参数后点击发送,响应会实时显示。

如果 CDD 中没有某个服务,或者你需要发送“非正常”报文来测试 ECU 的 NRC 处理,可以使用窗口底部的手动输入框,直接填入十六进制诊断报文。

4.3 自动化测试

对于需要反复执行或批量执行的诊断序列(例如刷写前的会话切换、安全解锁、写 DID),CANoe 支持通过CAPL 脚本自动化。例如保持会话的0x3E服务,可以在配置中启用“Send Tester Present”,设置周期后由 CANoe 自动周期发送。

五、总结

CAN 诊断的骨架是清晰的:ISO-TP 负责拆包组包,UDS 负责服务语义。理解了这个分层,无论是手写代码还是用工具排查问题,都能找到切入点。

C++ 开发中,小规模验证可以自己封装 ISO-TP 单帧/多帧逻辑;产品级项目建议直接使用 PCAN-UDS、开源 UDS 库或 OEM 提供的诊断协议栈,把精力留给诊断序列的业务逻辑。工具侧,CANoe 搭配 CDD 文件是效率最高的方案,适合测试工程师进行交互式诊断和自动化脚本开发。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
绝了!唐僧取经先被办证窗口问崩溃,教师资格证采矿证捕捞证一张不能少

绝了!唐僧取经先被办证窗口问崩溃,教师资格证采矿证捕捞证一张不能少

三言四拍
2026-09-27 19:24:04
随着阿拉米扬1-4,亚运会乒乓球男单决赛已诞生1席:中国名将在列

随着阿拉米扬1-4,亚运会乒乓球男单决赛已诞生1席:中国名将在列

侧身凌空斩
2026-09-28 13:00:07
耿同学又出手!揭《Nature》一论文造假,24个原始值完全一致,通讯作者已承认并撤稿

耿同学又出手!揭《Nature》一论文造假,24个原始值完全一致,通讯作者已承认并撤稿

材料科学与工程
2026-09-24 11:48:39
亚运会:时隔3天再赢世界第二!梁伟铿/王昶2-1晋级,决赛战最强黑马

亚运会:时隔3天再赢世界第二!梁伟铿/王昶2-1晋级,决赛战最强黑马

钉钉陌上花开
2026-09-28 12:49:09
游本昌女儿透露父亲去世前两三天选择不吃不喝:家人没有强行喂他或送医抢救,而是希望他在一个相对熟悉、有安全感的地方离去

游本昌女儿透露父亲去世前两三天选择不吃不喝:家人没有强行喂他或送医抢救,而是希望他在一个相对熟悉、有安全感的地方离去

极目新闻
2026-09-28 12:55:58
知名投资人曝刘欢真实死因是肝癌!8月底他曾在餐厅吃饭状态不错

知名投资人曝刘欢真实死因是肝癌!8月底他曾在餐厅吃饭状态不错

一个小豹子
2026-09-27 09:40:19
刘欢豪宅一览表:装修值千万,客厅能容百人,有私家酒吧,从不请保姆

刘欢豪宅一览表:装修值千万,客厅能容百人,有私家酒吧,从不请保姆

火鱼观点
2026-09-27 19:25:53
从低谷到夺金,接棒中国110米跨栏的陈圆将:“杀不死我的,只会让我更强大”

从低谷到夺金,接棒中国110米跨栏的陈圆将:“杀不死我的,只会让我更强大”

澎湃新闻
2026-09-28 13:54:29
美国农场主4千美元买中国三轮车,拆箱想退货,半月后狂定12台

美国农场主4千美元买中国三轮车,拆箱想退货,半月后狂定12台

爱下厨的阿酾
2026-09-28 02:30:59
网传烟草行业即将全军覆没,就靠6个“好汉”顶着,都不抽烟了吗

网传烟草行业即将全军覆没,就靠6个“好汉”顶着,都不抽烟了吗

慧翔百科
2026-09-28 10:56:38
“第一次感觉离死亡这么近!”男子称喝了几口隔夜鱼汤差点窒息,孩子哭着喊“爸爸不要死”……医疗专家解析

“第一次感觉离死亡这么近!”男子称喝了几口隔夜鱼汤差点窒息,孩子哭着喊“爸爸不要死”……医疗专家解析

都市快报橙柿互动
2026-09-28 00:14:52
林诗栋4-3大逆转!10连胜林昀儒 冲3金王 国乒包揽男单金银牌

林诗栋4-3大逆转!10连胜林昀儒 冲3金王 国乒包揽男单金银牌

念洲
2026-09-28 14:33:31
爆料中国女篮要重新洗牌,两大王牌面临淘汰,李梦最新动态惹争议

爆料中国女篮要重新洗牌,两大王牌面临淘汰,李梦最新动态惹争议

宗介说体育
2026-09-27 19:03:24
确认了!她系台湾间谍情报机关人员

确认了!她系台湾间谍情报机关人员

焦作日报
2026-09-27 15:33:27
邓亚萍谈日本男单全军覆没:男团夺冠后兴奋过了头,能战胜国乒出乎他们的意料;张本智和对中国队做了充分的准备,单打他的心态不一样了

邓亚萍谈日本男单全军覆没:男团夺冠后兴奋过了头,能战胜国乒出乎他们的意料;张本智和对中国队做了充分的准备,单打他的心态不一样了

极目新闻
2026-09-27 09:04:26
塞尔维亚总统武契奇宣布辞职

塞尔维亚总统武契奇宣布辞职

澎湃新闻
2026-09-28 02:47:02
这跟不穿有啥区别?三角区明显,41岁女星穿透视3D打印裙惹争议

这跟不穿有啥区别?三角区明显,41岁女星穿透视3D打印裙惹争议

铁锤妹妹是只猫
2026-09-26 19:04:43
女子千里赴约让情人白睡,2016年情夫和她缠绵完很满足,将她杀死并抛尸

女子千里赴约让情人白睡,2016年情夫和她缠绵完很满足,将她杀死并抛尸

汉史趣闻
2026-09-26 09:25:49
亚运会:单局遭遇5-21惨案!陈雨菲0-2不敌安洗莹,大魔王冲赛季第十冠

亚运会:单局遭遇5-21惨案!陈雨菲0-2不敌安洗莹,大魔王冲赛季第十冠

钉钉陌上花开
2026-09-28 11:39:09
亚运会:世界第1爆冷出局!冯彦哲/黄东萍0-2印尼混双,5连胜终结

亚运会:世界第1爆冷出局!冯彦哲/黄东萍0-2印尼混双,5连胜终结

钉钉陌上花开
2026-09-28 09:13:11
2026-09-28 14:44:49
新能源自动驾驶 incentive-icons
新能源自动驾驶
专注于半导体行业资讯
1015文章数 348关注度
往期回顾 全部

汽车要闻

神龙科技与Momenta达成全球战略合作 2027年起推新车

头条要闻

韩要求乌就公开朝战俘移交信息道歉 李在明:深感遗憾

头条要闻

韩要求乌就公开朝战俘移交信息道歉 李在明:深感遗憾

体育要闻

114项指控成立,曼城已经完蛋了吗?

娱乐要闻

好汉刘欢:一副好嗓子,一颗赤子心

财经要闻

标价298元核桃油, 实为大豆油冒充

科技要闻

智能体惹了多少祸,OpenAI自己没查清!

态度原创

时尚
教育
本地
游戏
艺术

女人过了三四十岁,一定要准备一件小西装,大方得体又显瘦

教育要闻

算了半天没算出来,越算越乱啊

本地新闻

中秋逛白塔寺,体验国医妙荟雅集

生化老玩家笑嘻了!新电影彩蛋太多:有枪也得找钥匙

艺术要闻

浙江最憋屈的烂尾别墅群,盖好了却没人敢住,如今野草堵门!

无障碍浏览 进入关怀版