4. 诊断会话管理:非默认会话的切换机制与S3Server超时实战
诊断会话管理,说白了就是ECU的“工作模式切换”。默认会话(Default Session)只能做基本的数据读取和故障码查询。但你要刷写软件、做标定、解锁高级功能,就得切换到非默认会话——编程会话(Programming Session)和扩展会话(Extended Session)。
我刚开始做AUTOSAR诊断栈时,觉得会话切换不就是发个10 02、10 03嘛,有什么难的?直到有一次,客户反馈ECU在产线刷写时频繁超时,我排查了整整两天才发现是S3Server定时器配置出了问题。嗯,从那以后我再也不敢小看这个模块了。
4.1 会话状态机:三个核心状态
UDS协议定义了三种标准会话,AUTOSAR在此基础上做了细化。咱们直接看状态机流转图:
这张图我建议你保存下来。每次配置会话参数时,对着这张图想清楚:当前会话能做什么,超时后会去哪里。
4.2 会话切换机制:10 02与10 03
切换会话用的是UDS服务10 (DiagnosticSessionControl)。请求格式很简单:
请求:02 10 [会话ID] [扩展数据(可选)]
响应:06 50 [会话ID] [P2Server_max] [P2StarServer_max]
会话ID的取值:
| 会话ID | 会话名称 | 典型用途 |
|---|---|---|
| 0x01 | 默认会话 | 基本诊断功能,读取DTC、数据标识符 |
| 0x02 | 编程会话 | 刷写软件、配置参数 |
| 0x03 | 扩展会话 | 标定、高级诊断、特殊功能 |
这里有个细节:响应中的P2Server_max和P2StarServer_max是告诉Tester,当前会话下ECU能接受的最大响应时间。我在项目中遇到过,Tester端配置的P2超时比ECU返回的值小,结果每次发完请求就超时,其实ECU还在处理。你想想看,这不是代码问题,是参数没对齐。
4.3 会话超时处理:S3Server的机制
S3Server是AUTOSAR里的一个定时器,用来监控非默认会话是否超时。它的工作原理很简单:
- 启动条件:进入非默认会话时,S3Server定时器启动。
- 刷新条件:每次收到有效的诊断请求(非物理寻址的TesterPresent除外),定时器重置。
- 超时动作:定时器溢出,ECU自动切回默认会话。
核心参数:S3Server超时时间
标准规定S3Server的典型值是5000ms。但实际项目中,我见过用2000ms的,也见过用10000ms的。关键看你的应用场景:
- 刷写场景:建议设长一点(8000~10000ms),因为刷写过程中可能有大块数据传输,中间间隔较长。
- 标定场景:建议设短一点(2000~3000ms),标定工具通常频繁发请求,超时短能及时释放资源。
4.4 S3Server超时配置实战
在AUTOSAR配置工具中(比如EB tresos、Vector DaVinci),S3Server的配置通常在Dcm模块的DcmDspSession部分。我以实际项目为例,展示配置步骤:
4.4.1 配置项清单
| 配置参数 | 路径 | 说明 |
|---|---|---|
| DcmDspSession.S3Server | Dcm / DcmDsp / DcmDspSession | 超时时间,单位ms,默认5000 |
| DcmDspSession.S3Server_Reset | Dcm / DcmDsp / DcmDspSession | 定时器重置条件,通常选"OnAnyRequest" |
| DcmDspSession.P2ServerMax | Dcm / DcmDsp / DcmDspSession | 响应超时,单位ms,默认50 |
| DcmDspSession.P2StarServerMax | Dcm / DcmDsp / DcmDspSession | 扩展响应超时,单位ms,默认2000 |
4.4.2 代码级配置示例
如果你用的是AUTOSAR 4.x版本,配置生成后的代码通常长这样:
/* Dcm_Cfg_SchM.h 中生成的会话配置 */
#define DCM_CFG_SESSION_DEFAULT_S3SERVER_MS 5000u
#define DCM_CFG_SESSION_EXTENDED_S3SERVER_MS 5000u
#define DCM_CFG_SESSION_PROGRAMMING_S3SERVER_MS 8000u
/* Dcm_Cfg.c 中的会话表 */
const Dcm_SessionConfigType Dcm_SessionConfig[DCM_CFG_NUM_SESSIONS] = {
/* Default Session */
{
.SessionId = 0x01,
.S3ServerMs = DCM_CFG_SESSION_DEFAULT_S3SERVER_MS,
.P2ServerMaxMs = 50u,
.P2StarServerMaxMs = 2000u
},
/* Extended Session */
{
.SessionId = 0x03,
.S3ServerMs = DCM_CFG_SESSION_EXTENDED_S3SERVER_MS,
.P2ServerMaxMs = 50u,
.P2StarServerMaxMs = 2000u
},
/* Programming Session */
{
.SessionId = 0x02,
.S3ServerMs = DCM_CFG_SESSION_PROGRAMMING_S3SERVER_MS,
.P2ServerMaxMs = 200u, /* 刷写时响应慢,设大一点 */
.P2StarServerMaxMs = 5000u
}
};
我的经验:编程会话的P2ServerMax我习惯设到200ms以上。为什么?因为刷写过程中,ECU要擦除Flash、校验数据,这些操作很耗时。如果P2设得太短,Tester会频繁重发请求,反而拖慢刷写速度。
4.5 避坑指南:S3Server常见问题
我曾经踩过的坑:
- 坑1:S3Server设得太短,刷写中断——有一次客户反馈刷写到一半就断了,查日志发现S3Server只有2000ms,而刷写过程中有3秒的擦除操作。Tester没发请求,ECU以为超时了,直接切回默认会话。解决方案:把编程会话的S3Server改成10000ms。
- 坑2:P2ServerMax和S3Server混淆——有人把P2ServerMax当成会话超时来配,结果ECU每次响应稍慢就切会话。记住:P2是单次请求的响应超时,S3是会话级别的空闲超时。
- 坑3:TesterPresent不重置S3Server——标准规定,只有非物理寻址的TesterPresent(0x3E)才能重置S3Server。如果你用物理寻址发3E,ECU不会重置定时器。这个细节很容易被忽略。
4.6 实战建议:如何配置合理的超时参数
我总结了一套配置策略,你可以直接拿去用:
| 场景 | S3Server | P2ServerMax | P2StarServerMax |
|---|---|---|---|
| 默认会话 | 5000ms | 50ms | 2000ms |
| 扩展会话(标定) | 3000ms | 50ms | 2000ms |
| 编程会话(刷写) | 10000ms | 200ms | 5000ms |
当然,这些值不是死的。你实际调试时,可以用CANoe或PCAN抓一下总线日志,看看Tester发请求的间隔。如果间隔大于S3Server,那就得调大超时,或者让Tester多发3E保活。
嗯,会话管理这块内容就这些。核心就三点:状态机流转、超时参数配置、避坑经验。你配置的时候,多想想实际场景,别死磕标准值。