ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AutoSar 0x11复位服务:Dcm-BswM-EcuM联动配置全解析

AutoSar 0x11复位服务:Dcm-BswM-EcuM联动配置全解析 收到测试报告说“用诊断仪发0x11 01ECU 没正响应”或者“正响应有了但 ECU 根本没重启”这应该是做 AutoSar 诊断集成最典型的痛点之一。问题基本都出在 Dcm、BswM、EcuM 这三个模块的联动没有配齐而不是单纯某个模块的事。这篇文章就把0x11服务从 Dcm 解析、BswM 决策、EcuM 执行这条链路完整拆开按保姆级的粒度告诉你每一步配什么、为什么这么配、配完怎么验收。适合正在做 AutoSar 基础软件集成、被诊断复位问题反复折磨的工程师。不管你是用 Vector、ETAS 还是 EB 的配置工具下面讲的都是概念级的逻辑链条具体菜单名你可能要对照自己工具的界面但思路可以直接套用。1. 0x11复位为什么需要“绕道”BswM和EcuM先说清楚一个很容易混淆的点Dcm 模块只是 UDS 协议层面的解析器它负责检查收到的0x11请求是否合法、当前会话是否允许、安全等级够不够然后构造正响应或负响应。但 Dcm 本身不应该去执行硬件复位更不应该直接调用 MCU 驱动里的复位接口。1.1 Dcm、BswM、EcuM分别扮演什么角色Dcm协议翻译官。把网络上的诊断请求解析成内部数据结构校验完合法性后回响应然后把“这个人想要复位”这件事通知出去。BswM仲裁中心。接收来自 Dcm、ComM、EcuM 等多个模块的模式请求按照预先配好的规则决定要不要执行动作、按什么顺序执行。EcuM电源和复位状态机。它拥有 ECU 从启动到运行、再到下电或复位的完整状态管理权负责在复位前调用各个 BSW 模块的 Shutdown 接口最后才真正触发硬件复位。如果只是想要“能复位”确实可以用最粗暴的方案在 Dcm 收到0x11服务后直接调Mcu_PerformReset()。我在早期项目里就见过这种写法Demo 阶段一切正常一到带 NvM、Dcm、Com 全量集成就出问题DTC 快照没来得及写进 NvM复位后诊断上下文全丢CAN 控制器来不及静默总线上直接报 Bus Off应用层没有机会通知重启后校准参数丢失。所以 AutoSar 标准的做法是让 Dcm 把复位请求交给 BswMBswM 根据当前整车或 ECU 的状态跑一段 ActionList在复位前完成必要的准备工作最后由 BswM 请求 EcuM 走正式复位流程。这条链路看着多绕了两步但在量产项目里少踩很多坑。1.2 一次完整的0x11服务处理流程以最常见的0x11 01硬复位为例实际处理链路是这样诊断仪通过 CAN 把02 11 01发到 ECU。Dcm 判断当前会话是否允许该子功能。比如只配了 ExtendedSession 允许执行而当前在 DefaultSession就会回 NRC0x7E。如果配置了安全等级Dcm 还会检查是否已经通过 SecurityAccess。没解锁就回 NRC0x33。校验通过后Dcm 构造正响应06 71 01 00 00 00 00响应数据具体长度取决于配置比如有些会带 powerDownTime。Dcm 把正响应交给 CanTp/CanIf 传输路径然后通知 BswM“有一个复位请求进来了”。BswM 收到模式请求后去匹配当前所有 ModeCondition。命中的 ActionRule 执行对应的 ActionList。ActionList 里可能先通知 App 保存数据也可能先让 NvM 刷写指定块最后执行“请求 EcuM 复位”这个动作。EcuM 进入复位相关状态按顺序调用各 BSW 模块的 Shutdown 回调最后调用 MCU 驱动完成硬件复位。ECU 重新上电启动EcuM 识别到本次唤醒源是 Reset进入正常的 RUN 状态。这一整条链路里Dcm 到 BswM 的“通知”方式、BswM 到 EcuM 的“动作”方式在不同工具链里实现不太一样。但核心思路是一致的Dcm 只负责说“我想复位”BswM 决定“怎么复”EcuM 负责“真的复”。2. Dcm配置手记0x11子功能、会话与安全等级的匹配Dcm 侧配置是整条链路的第一关。这里配不好后面 BswM 和 EcuM 再对也没用因为请求根本走不到触发环节。2.1 在配置工具里找到0x11服务容器打开你的 AutoSar 配置工具Dcm 模块下找到DcmDsp→DcmDspEcuReset。如果找不到这个容器先确认 DcmDsp 里有没有把 ECUReset 服务挂到当前使用的诊断协议上。有些工具需要先在“服务列表”里把0x11服务加进去才会生成对应的容器。有一个容易混淆的地方先提醒一下如果 Dcm 没有使能0x11服务诊断仪发请求时 Dcm 会返回 NRC0x11这个 NRC 表示“服务不支持”。也就是说请求字节里的 SID 是0x11负面响应码也是0x11初学的时候特别容易看晕。2.2 子功能怎么选、怎么配0x11服务的标准子功能主要有这几个子功能名称典型语义0x01hardReset硬复位相当于 MCU 冷启动通常要从 Bootloader 完整跑一遍0x02keyOffOnReset钥匙电关断后复位通常和 KL15 硬线状态强相关0x03softReset软复位一般希望只复位应用层不重新跑 Bootloader0x04rapidPowerShutDown快速下电正响应里会带 powerDownTime 参数在DcmDspEcuReset下按子功能建立配置容器每个子功能要配置几个关键项允许的会话DcmDspEcuResetSubFuncSessionRef指向某个DcmDspSession。量产项目里0x01和0x03一般只开放给 ExtendedSession有些 OEM 也要求在 ProgrammingSession 下可用。安全等级如果 OEM 规定复位需要先解锁就在子功能配置里关联 SecurityLevel。这里要注意测试阶段经常有人把安全等级设得太严导致开发时用诊断仪发0x11一直被回0x33还误以为是 BswM 链路问题。开发阶段可以先不配安全等级量产科再收紧。SuppressResponseBit新版本 UDS 协议支持抑制正响应位请求第二个字节的最高位。如果客户要求支持就要在配置里把抑制位功能打开。实测中这个功能会让测试用例多出很多分支不要求就默认关掉。复位延时这是非常关键的一个参数。Dcm 必须先保证正响应发出去了再真正触发复位。如果正响应还在 CanTp 发送队列里MCU 就已经断电复位诊断仪那边就会看到“请求发出后无响应”测试直接失败。很多工具里有 ResetDelayTime 之类的参数单位通常是秒建议先配 100ms 左右确保 CAN 帧完整发出去。具体名字在不同厂商工具里不一样常见的有DcmDspEcuResetResetDelayTime或类似名称本质都是给正响应发送留时间窗口。下面是一份典型的0x11 01配置参考配置项示例值说明SubFunction ID0x01hardResetSessionRefExtendedSession仅扩展会话可执行SecurityLevelRef不关联开发阶段量产科按 OEM 要求加上SuppressRespBit不支持不处理抑制正响应位ResetDelay100ms保证正响应先发出去复位动作入口指向 BswM 的模式请求端口这是后面第 5 节要重点确认的地方一个常见误区是只在 Dcm 里配了子功能却没有配“动作入口”。这样 Dcm 会正常回正响应但复位请求没有继续往下传递现象就是“Tester 看到正响应了ECU 却没动静”。后面讲联动时会专门说怎么查这个问题。3. BswM配置手记从模式条件到复位ActionList的完整链条BswM 是 AutoSar 里一个以状态规则为驱动的基础软件模块。很多新手第一次打开 BswM 的配置界面会发懵里面全是 ModeRequestPort、ModeCondition、LogicalExpression、ActionRule、ActionList 这些概念。其实把它理解成一张“规则表”就行当某些条件成立时就执行一组预设动作。3.1 BswM里的核心对象怎么理解ModeRequestPort模式请求端口。每个端口代表一个模块对 BswM 发出的模式请求比如 Dcm 的复位请求、ComM 的通信模式请求、EcuM 的唤醒请求。ModeCondition针对端口上某个模式值的判断条件比如“DcmResetRequest 等于 RESET_REQUESTED”。LogicalExpression把多个 ModeCondition 用 AND / OR 组合起来形成复杂的判定表达式。ActionRule一条规则包含一个逻辑表达式和对应的 ActionList。表达式成立时执行 ActionList。ActionList动作列表按顺序执行多个具体动作。在 0x11 联动场景里BswM 要做的事情就是监听 Dcm 发来的复位请求一旦收到就执行一个包含了“通知应用”和“请求 EcuM 复位”的 ActionList。3.2 创建复位请求的模式端口在 BswM 配置里新增一个 ModeRequestPort模式类型建议自定义成DcmResetType包含两个模式值NO_REQ和REQ_RESET。把这个端口的来源模块指向 Dcm。有的工具会在生成代码里自动创建对应的接口函数你在 Dcm 生成的代码里会看到调用这个函数的地方。实际上不同工具的做法有差异。有的栈是 Dcm 内部生成一个回调函数你需要在回调里手动调用 BswM 的模式请求接口有的栈则是通过 RTE 端口自动连接配置项里选一下就行。无论哪种方式核心目标都一样Dcm收到合法复位请求后要让 BswM 的模式请求端口变成 REQ_RESET 状态。3.3 配置ActionRule和ActionList接下来创建一个 ModeCondition判断DcmResetType REQ_RESET。再创建一个 ActionRule把这条 ModeCondition 作为触发条件。ActionList 的配置顺序非常关键我建议的默认顺序是通知应用层准备复位通过 ExecuteFunction 或者 RTE 端口回调 App让应用有机会保存标定、落盘数据。处理 NvM 写请求如果某些关键块需要在复位前同步写入可以在这一步请求 NvM 写。不过更规范的做法是把 NvM 写放在 EcuM 的 shutdown 序列里BswM 这步只做应用层的数据准备。请求 EcuM 复位这是动作列表里最后一步选择 EcuM 复位动作并把 ShutdownTarget 指向 Reset 类型。很多人在这里会配错一个东西ActionRule 的优先级。BswM 里可以同时存在几十条规则如果复位规则的触发条件和别的规则有重叠而复位规则优先级又低就可能出现“BswM 确实收到了复位请求但先执行了另一条规则然后状态被覆盖复位动作没执行”的情况。配置完成后建议把复位移到高优先级区间或者用互斥条件把其他规则在复位期间挡住。4. EcuM配置手记让硬复位、软复位、快下电各归其位EcuM 是整个复位链路里真正“动手”的模块。它管着 ECU 生命周期里的状态切换也负责在复位前把基础软件按顺序停掉。4.1 确认Reset是合法唤醒源这一步很多人忽略。ECU 复位之后重新上电EcuM 会先判断自己是被什么唤醒的。如果 Reset 没有被配成合法的唤醒源EcuM 可能不认为这是一次正常启动而是进入休眠或等待其他唤醒事件导致 ECU 启动后不在 RUN 状态诊断服务起不来。在 EcuM 的 WakeupSource 配置里要确保有一个唤醒源对应RESET唤醒原因。不同芯片的具体写法不一样但概念都一样硬件上电或复位引脚触发的启动必须被 EcuM 识别为有效唤醒。如果这个问题没配好现象非常奇怪用诊断仪发0x11 01正响应也正常MCU 也确实复位了但复位后 ECU 好像“睡死”了诊断仪再发任何请求都没响应。很多人会认为是复位没成功实际上启动链路根本没走完。4.2 针对不同子功能设置不同的复位目标EcuM 的 ShutdownTarget 一般有 POWER_OFF、RESET、GO_DOWN 等几种。0x11 服务按子功能应该映射到不同目标0x01 hardReset映射到 RESET而且这个 RESET 要确保 MCU 真正冷启动Bootloader 会重新执行。一般由 ECU 驱动层调用Mcu_PerformReset()实现。0x03 softReset这个需要特别注意。很多栈里 softReset 最终也调了Mcu_PerformReset()效果和 hardReset 几乎没有区别。如果你的 OEM 明确要求 softReset 只复位应用、不跑 Bootloader那你可能需要自定义一条复位路径比如跳过 MCU 硬件复位而是跳转到应用的复位向量或者让 OS 重新启动。这件事一定要在设计阶段和 OEM 确认清楚否则测试阶段会被“softReset 不应该进 Bootloader”这种用例卡住。0x04 rapidPowerShutDown这个不是严格意义上的复位而是“快速下电”。它的正响应里会带一个 powerDownTime 参数EcuM 要根据这个参数决定多快切断电源。如果你把0x04也简单映射成硬件复位很可能违反 OEM 的电源管理策略。4.3 shutdown序列里的NvM写入EcuM 在执行复位前会走一遍 shutdown sequence逐个调用已使能 BSW 模块的 shutdown 处理。NvM 通常会在这一阶段把脏块写进非易失存储。如果应用层在收到复位通知后修改了某些标定参数但这些修改只有在 NvM 轮询周期里才会被标记为 dirtyEcuM 的 shutdown 到来时可能发现没有待写块数据就丢了。一个实际项目里踩过的坑应用在 BswM 通知里更新了标定参数然后 BswM 马上去请求 EcuM 复位。结果 EcuM 进入 shutdown 时NvM 认为那个块不是 dirty跳过了写入最后参数恢复成旧值。解决的办法是在 BswM 的 ActionList 里先调用一次NvM_SetBlockDirty()或者让应用调用NvM_WriteBlock()同步写完再继续确保数据真实落盘。5. 端口联动的关键配置Dcm通知、BswM动作、EcuM目标怎么接上前几节是把三个模块单独讲了一遍但实际配置时最耗时间的往往是“接线”这一步。这里把联动的关键点单独拉出来说。5.1 Dcm和BswM之间的通知通道Dcm 的DcmDspEcuReset下每个子功能通常都会有一个字段用来指定复位动作的“去向”。最常见的做法是让子功能指向一个 BswM 模式请求端口或者指向一个由集成层实现的回调函数。以我常用的配置思路为例Dcm 生成的代码里处理0x11的位置会有一个类似这样的跳转/* 伪代码示意具体函数名以你工程生成为准 */ static void Dcm_HandleEcuReset_0x01(void) { /* 先保证正响应已经交给传输层 */ Dcm_SendPositiveResponse(0x11, 0x01); /* 延时后触发BswM */ BswM_ResetIndication(BSWM_RESET_HARD); }如果工具配置完整这段代码是自动生成的。但我在项目里也见过配置工具版本太老、Dcm 侧没有可视化端口可选的情况这时候就得在集成层手写一段 glue code把 Dcm 的回调映射到 BswM 的请求接口。写这种代码之前一定要翻一下你所用 AutoSar 栈的集成手册确认函数签名和调用上下文否则栈升级一次就挂一次。5.2 BswM和EcuM之间的动作映射BswM 的 ActionList 里最后一步应该是请求 EcuM 复位的动作。在 BswM 配置界面里这个动作可能显示为EcuM_Shutdown或EcuM_RequestReset之类。关键是确认 ShutdownTarget 或 ResetType 参数指向的是RESET而不是POWER_OFF或SLEEP。这里有个非常经典的复制粘贴错误从别的项目拷贝 BswM 配置时ActionList 里带过来的目标还是上一个项目的POWER_OFF。结果 Dcm、BswM 链路全通正响应也正常ECU 也确实“复位”了但实际走的其实是下电流程整个系统断电又上电现象和硬复位很像可时序和对 NvM 的处理完全不同再遇到一点硬件电源设计上的差异就会偶发复位失败。5.3 一个联动自查清单配置完成后我建议按这个清单逐项自查检查项配好是什么样Dcm 0x11子功能已使能发请求不会回 NRC 0x11子功能会话/安全等级正确发请求不会回 NRC 0x7E/0x33Dcm动作入口指向BswM生成的Dcm代码能调到BswM接口BswM模式端口收到Dcm信号ModeCondition里有对应判断BswM ActionRule已建立复位规则优先级足够高ActionList最后一步是EcuM复位ShutdownTarget是RESETEcuM Reset唤醒源已配置复位后能正常进RUN状态NvM关键块在复位前能落盘数据不丢校准不还原这张表建议直接贴到你的开发文档里每次换项目、换芯片、换工具链都照着过一遍。6. 配置完0x11之后建议按这个清单做一轮验证配置完成只是开始验证才是真正发现问题的地方。下面是我在实际项目里跑过的验证步骤和常遇到的问题。6.1 用诊断仪和CANoe做基础验证先用诊断仪或 CANoe 的 UDS 测试发送0x11 01观察几个点有没有正响应正响应里的子功能字节是不是0x01正响应之后ECU 是不是真的复位用 CANoe 看总线信号或者看 ECU 的供电电流波形最直观。复位后 ECU 能否在预期时间内完成启动并对后续诊断请求正常响应如果正响应丢了优先怀疑 Dcm 的 ResetDelay 太短。把延时拉长到 200ms 再试如果问题消失就是发送时序问题。如果正响应正常但 ECU 没复位优先去查 BswM 的 ActionRule 有没有被触发。在调试器里给 BswM 的模式请求处理函数打断点发一次0x11 01看命不命中。如果断点没进说明 Dcm 到 BswM 这条“线”没接上如果断点进了但 ActionList 没执行说明条件匹配或优先级有问题如果 ActionList 执行了但没复位那就去 EcuM 的复位入口下断点。6.2 常见故障现象与排查方向下面几个是 0x11 配置问题里出现频率最高的我按“现象 → 可能原因 → 处理方向”整理成表现象可能原因处理方向正响应丢失诊断仪超时ResetDelay 太短正响应还没发出去加大 ResetDelay验证发送窗口正响应正常ECU没复位Dcm动作入口没指向BswM检查生成的Dcm代码确认回调BswM收到请求但没动作ActionRule条件不满足或优先级低检查ModeCondition和规则优先级ActionList执行了但没复位EcuM目标配置成了POWER_OFF/SLEEP把ShutdownTarget改成RESET复位后ECU“睡死”Reset唤醒源没配EcuM增加RESET唤醒源配置复位后标定丢失NvM块没在复位前写入BswM通知App先刷NvM或检查dirty位0x11 03无法区分软硬复位softReset也走了硬件复位自定义应用级复位路径发0x11回复NRC 0x22Dcm配置了请求条件条件不满足检查Dcm的RequestCondition链路0x22这个情况特别容易让人懵。因为这时候 Dcm、BswM、EcuM 看起来都对但 Dcm 在正响应之前先去做了一次条件检查BswM 当前状态让检查失败了Dcm 就直接回了0x22。遇到这个 NRC先别急着查 EcuM去 Dcm 的请求条件配置里看有没有勾选前置条件端口。6.3 用调试器做整链路断点验证最可靠的验证方式是拿调试器在几个关键位置下断点一次性确认整条链路Dcm 处理0x11的入口函数Dcm 调用 BswM 的指示函数BswM ActionList 里第一个动作BswM 请求 EcuM 复位的地方Mcu_PerformReset()内部。从诊断仪发一次0x11 01看断点是否按顺序全部命中。哪个断点没进问题就出在哪个环节的前一段。这套方法在集成阶段能省下大量“猜来猜去”的时间。7. 一点个人经验复位子功能扩展时最值得留意的坑最后分享一个我每到一个新项目都会做的事建一张“复位子功能映射表”把每个子功能对应的会话、安全等级、BswM规则名、EcuM复位目标、OEM期望行为全部列清楚。这张表在项目初期看起来是纯文档工作但等到 OEM 突然说“软复位行为要改一下”“要在快速下电里加一个电源序列”的时候你就知道有多值了。比如有一次量产前测试OEM 要求 hardReset 之后DCM 里的故障码状态快照必须保留。我们排查到最后发现问题不是复位链路而是 NvM 里 DTC 快照的写入条件是“Dcm 进入非默认会话”而诊断仪只发了0x11 01没有先切会话快照根本没生成。这种问题光靠看 Dcm/BswM/EcuM 的配置是看不出来的必须回到 UDS 测试流程本身去分析。另外一个小技巧在开发阶段增加一个专用的 DID 只读接口用来读 MCU 的复位原因寄存器。这样测试人员报告“复位失败”或“启动异常”时你可以先区分是上电复位、看门狗复位还是软件复位很多疑难杂症瞬间就有了排查方向。0x11 的配置链路由三个模块共同决定缺一个环节都不会正常工作。把上面几节的内容按顺序过一遍绝大多数复位问题都能在半小时内定位到具体模块剩下的就是改参数、重新生成代码、再跑一轮验证的事。
返回列表