汽车电子诊断协议编程:UDS协议在动力域控制器上的完整实现流程
动力域控制器(发动机ECU/VCU/MCU)跑UDS不是“收到一帧回一帧”,而是CAN/ISO-TP收字节 → DSD层查会话与安全等级 → DSP层分发服务 → 业务模块执行。整条链任何一道闸门不过直接回NRC,根本进不到执行层。
一、协议栈与帧格式
UDS在应用层,Classic CAN下长报文走ISO-TP(ISO 15765-2):单帧≤7字节;超了走首帧+流控+连续帧,接收方用BS/STmin控速。
UDS三类报文格式固定:
请求:SID [子功能] [数据]
正响应:SID+0x40 …
负响应:7F SID NRC
例:读DID 22 F1 90 → 62 F1 90 ...;权限不够回 7F 2E 33。
二、会话与安全闸门
动力域至少三档会话:
默认会话:只读故障码、版本号
扩展会话:写标定/配置、例程控制
编程会话:刷写专属,常伴随停周期报文
S3定时器超时(典型5s)自动退回默认会话,诊断仪用3E 00保活。
0x27安全访问是种子-密钥:ECU回seed,诊断仪按OEM算法算key回传,比对通过才解锁。锁定计数、失败延时、掉电保持按项目定,别只放RAM。
三、服务分发主循环
void uds_indicate(uint8_t*sid, uint8_t*req, uint16_t len){
uint8_t s = req[0];
if(!session_allowed(s)){ uds_neg(s,0x7E); return; } // 当前会话不支持
switch(s){
case 0x10: svc_session(req,len); break;
case 0x22: svc_read_did(req,len); break;
case 0x2E: svc_write_did(req,len); break;
case 0x19: svc_dtc(req,len); break;
case 0x14: dtc_clear(req); break;
case 0x27: svc_security(req,len); break;
case 0x31: svc_routine(req,len); break;
case 0x34: case 0x36: case 0x37: svc_transfer(req,len); break;
default: uds_neg(s,0x11);
}
}
正响应统一resp[0]=sid+0x40,负响应7F sid nrc。
四、DID读写:查表不硬编码
0x22/0x2E靠DID映射表,别在switch里写死业务逻辑:
typedef struct {
uint16_t did;
uint8_t len;
uint8_t need_sec; // 是否需要安全解锁
int (*read)(uint8_t*out);
int (*write)(const uint8_t*in);
} did_entry_t;
static const did_entry_t did_tbl[] = {
{0xF190, 17, 0, read_vin, NULL},
{0x0100, 2, 0, read_rpm, NULL},
{0x2001, 4, 1, NULL, write_cal_torque},
};
写DID前查need_sec和当前安全等级,没解锁回NRC 0x33;标定值写NvM,运行参数只改RAM。
五、DTC与快照
动力域故障不是“存个码”就行,0x19要按状态掩码返回DTC+快照(车速/电压/温度)+扩展数据(老化计数)。
DTC状态字按ISO 14229状态位维护:testFailed、confirmed、warningIndicator
快照在故障置位瞬间锁存,别事后读当前值
刷写前85 02关DTC设置,避免擦Flash刷出一堆假故障
14清码要清状态位+快照+计数,别只清confirmed
六、慢操作回0x78
读大块数据、擦Flash、校验签名都别卡在中断里等。处理超P2先回7F SID 78,主循环继续跑,完了再发正响应:
if(op_need_long_time()){
uds_neg(sid,0x78);
job_post(&slow_job); // 后台任务
return;
}
动力域刷写顺序固定:
10 02→27 01/02→31擦除→34请求下载→36分块→37结束→11复位
0x36数据块建议按Flash页对齐,写前关中断或放专门Flash任务,别在ISO-TP回调里擦写。
七、动力域落坑
字节序:DID多字节按小端,DID号本身大端,规范写死
S3超时:非默认会话下周期报文该停就停,别一边保活一边发扭矩
0x78不是错误:诊断仪收到要继续等,别当失败
安全等级随会话复位:切回默认会话必须清解锁状态
P2/P2*:动力域默认P2可放宽到100ms,编程会话更长
DTC防误报:传感器标定未完成、上电自检期别开记录
Bootloader边界:0x34下载地址不能覆盖Boot区,写保护位提前锁
按“ISO-TP收帧→会话/安全闸门→DID表分发→DTC状态机→慢操作0x78→刷写走编程会话”落地,动力域UDS才是可量产的:读得出扭矩转速、写得进标定、刷得了固件、故障码不带假。架构核心是把权限检查和业务执行拆开,Dcm只做分发,具体数据交给各业务模块回调。





