news 2026/2/10 11:49:13

AUTOSAR CAN NM与UDS协同工作模式通俗解释

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AUTOSAR CAN NM与UDS协同工作模式通俗解释

AUTOSAR CAN NM与UDS协同工作模式:从“唤醒”到“休眠”的全链路实战解析


一个典型的诊断场景,你是否熟悉?

设想这样一个画面:
深夜,一辆智能电动车静默地停在地下车库。突然,远程诊断系统启动——云端指令通过蜂窝网络下发,要求读取某ECU的实时状态数据。

指令到达网关后,被封装成一条UDS $10 进入会话的CAN报文,发送至目标ECU。此时该ECU早已进入低功耗睡眠状态,总线沉寂。

但就在这一帧CAN信号抵达的瞬间,奇迹发生了:

  • ECU的CAN控制器检测到有效电平,触发硬件中断;
  • MCU被唤醒,电源管理模块开始上电;
  • 软件栈层层启动,CanIf识别出这不是普通数据而是“关键事件”;
  • CanNm模块随即广播NM报文:“我醒了!”;
  • Dcm模块接收并处理诊断请求;
  • ComM判断通信正在进行,阻止系统过早休眠;
  • 数秒后,数据上传完成,Tester停止发包;
  • 定时器超时,ComM释放通信权限;
  • CanNm确认无活动,最终带领节点回归Bus-Sleep……

整个过程如行云流水,背后正是CAN NMUDS在AUTOSAR架构下的深度协同。

今天我们就来拆解这套机制——它不是两个协议的简单叠加,而是一套精密的状态联动系统,关乎整车功耗、诊断成功率和OTA升级稳定性。


先搞清楚:谁管什么?它们为什么必须合作?

我们先别急着看代码或状态机。先把角色捋清。

CAN NM:我是网络的“守夜人”

它的核心任务就一个字:省电

现代车上几十个ECU,如果每个都一直开着CAN收发器监听总线,光待机功耗就能把电池耗光。所以必须让不干活的节点“睡觉”。

但问题来了:怎么睡?什么时候醒?谁说了算?

CAN NM的答案是——分布式自治

每个节点自己决定是否睡觉,但要靠一种特殊的“心跳包”(即NM报文)告诉邻居:“我还在线”。只要有一个节点还在发心跳,其他节点就不能睡。

就像宿舍楼里最后一个熄灯的人,得确认所有人都不用灯了才能关总闸。

但它不管你在传什么数据,只关心一句话:有没有人在用网络?


UDS:我是诊断的“特使”

它不管节能,也不管通信调度,它只专注一件事:完成诊断任务

无论是读故障码、刷程序还是远程配置参数,它都需要建立可靠的端到端通信通道。

关键在于:即使ECU睡着了,我也能把它叫醒

这就像半夜敲门送快递——哪怕屋里没人应声,只要你按了门铃,屋主就得起床开门。

但在现实中,如果快递员敲完门转身就走,主人刚开完门发现没人,又得重新锁门上床……效率极低。

同理,在汽车里,不能每次诊断请求都引发一次完整的唤醒-休眠循环。这就需要和“守夜人”CAN NM配合好:我来的时候你帮我撑住网络,等我办完事再一起退场。


所以,真正的主角其实是——ComM

你可能会问:既然CAN NM和UDS各司其职,那它们之间怎么协调?

答案是:中间有个裁判员,叫ComM(Communication Manager)

你可以把它理解为“通信资源调度中心”。

  • 当UDS说:“我要干活!” → ComM记一笔:当前有通信需求。
  • 当CAN NM说:“我看没人发消息啊?” → ComM查台账:还有诊断在跑,不准休眠!
  • 直到UDS明确表示:“我干完了。” → ComM才允许NM进入休眠流程。

所以,三者关系可以总结为:

UDS发起请求,ComM做出决策,CAN NM执行动作。


深入内核:一次诊断唤醒背后的全流程拆解

让我们以一个最典型的场景为例——远程诊断唤醒,一步步追踪软件栈中的执行路径。

Step 1:物理层唤醒 —— “有人敲门了!”

  • 外部诊断仪发送一帧标准UDS请求,例如0x7DF发送到0x7E8
  • 报文到达目标ECU的CAN收发器;
  • 即使MCU处于STOP模式,CAN控制器仍处于待机监听状态;
  • 收到匹配ID的帧(可通过硬件滤波器配置),触发Wakeup Interrupt
  • MCU退出低功耗模式,开始初始化外设与基础驱动。

📌注意点
并非所有CAN帧都能唤醒!必须在CanIf中正确配置“Wakeup Source”,通常只允许诊断帧(如0x7DF)和NM帧(如0x600)触发唤醒,避免雨刮器信号之类无关报文频繁唤醒系统。


Step 2:网络激活 —— “我上线了,请保持通联!”

MCU启动后,第一件事就是通知网络管理层:“我已经醒了”。

这个动作由CanNm完成:

// 启动后立即调用 CanNm_Init(); CanNm_NetworkStart();

随后,CanNm进入Repeat Message State,开始周期性广播NM报文(如0x601):

Byte 0Byte 1~7
Node ID控制信息

这些报文会被同一网络组内的其他节点接收到,从而同步感知到“有人上线”,暂停自身休眠倒计时。

同时,PduR将收到的诊断PDU路由给Dcm模块进行处理。


Step 3:诊断服务响应 —— “我在,你说。”

Dcm模块接收到$10 03(进入扩展会话)请求,开始处理。

此时最关键的动作是:

void Dcm_ProcessDiagnosticRequest(void) { // 更新诊断活跃定时器(例如设为5s) Dcm_SetTimer(DCM_DIAG_TIMER, 5000); // 告知ComM:现在需要全通信模式 ComM_Dcm_SetComStatus(COMM_FULL_COMMUNICATION); }

这一句调用至关重要!

它相当于向ComM提交了一份“通信保单”:接下来一段时间内,请务必维持网络畅通

ComM收到后会更新内部状态,并通知CanNm:“别想着睡觉,有人要用网。”


Step 4:维持连接 —— “我还活着,请继续等待。”

很多工程师忽略了一个细节:诊断仪并不会连续发请求

比如执行安全访问$27,可能需要几秒钟计算种子密钥。这段时间如果没有额外动作,ComM可能误判为“空闲”,进而释放通信,导致后续响应失败。

解决办法就是使用Tester Present ($3E)

诊断仪定期(如每2秒)发送$3E 00,表示“我还在,别断线”。

Dcm收到后再次刷新定时器并调用:

ComM_Dcm_SetComStatus(COMM_FULL_COMMUNICATION);

这样,ComM就会不断续期,CanNm也持续发送NM报文,形成正向反馈闭环。


Step 5:优雅退场 —— “任务结束,准备关灯。”

当诊断仪完成所有操作,不再发送任何请求。

这时会发生什么?

  • Dcm内部的诊断定时器逐渐递减;
  • 到达零时,自动调用:

c ComM_Dcm_SetComStatus(COMM_NO_COMMUNICATION);

  • ComM检测到所有客户端(包括App、Dcm等)均释放通信;
  • 向CanNm发出“允许休眠”信号;
  • CanNm进入Prepare Bus-Sleep Mode,启动T_WaitBusSleep计时器(典型值2s);
  • 若期间未收到新的NM报文或本地请求,则最终进入Bus-Sleep Mode
  • ECU可进一步进入深度低功耗模式。

整个过程干净利落,既保障了诊断完整性,又避免了资源浪费。


状态流转图:一张图看懂生命周期

下面是基于AUTOSAR规范提炼的核心状态转换逻辑(文字描述 + 关键条件):

[Bus-Sleep Mode] ↑ (Wake-up by CAN frame: UDS or NM) ↓ [Prepare Bus-Sleep Mode] ↑ (No activity for T_ReadySleep < T_WaitBusSleep) ↓ [Network Mode: Repeat Message] → 发送首条NM报文 ↓ [Ready Sleep State] ←—————┐ ↓ │ [Normal Operation State] │ │ │ (Local Tx request / Rx NM) ——┘

关键跳转条件说明:

状态跳转触发条件
Sleep → Prepare Bus-Sleep唤醒中断发生,开始检查网络需求
Prepare → Repeat Message本地有通信需求(如诊断请求)
Any → Ready Sleep收到他人NM报文,表明网络已激活
Normal Op. → Ready Sleep本地无新请求且超时
Ready Sleep → Prepare Bus-Sleep无任何NM活动超过T_ReadySleep
Prepare → Bus-SleepT_WaitBusSleep超时且无事件

⚠️ 特别提醒:若在Prepare阶段收到新NM帧或诊断请求,必须立即返回Repeat Message,防止“即将休眠”时被打断造成通信丢失。


实战避坑指南:那些年我们踩过的“休眠陷阱”

理论讲得再清楚,不如几个真实案例来得震撼。以下是项目中高频出现的问题及解决方案。

❌ 坑点1:刷写中途掉线,OTA失败率高

现象
在Flash编程过程中,ECU突然进入休眠,导致$36 TransferData响应未发出,刷写失败。

根因分析
虽然诊断工具一直在发$3E保活,但Dcm模块未正确绑定ComM通道,导致ComM认为“没有通信需求”,提前释放了网络。

修复方案
- 检查ComMConfigurationSet.ComMChannel中是否包含Dcm使用的PduR通道;
- 确保DcmDslDsdConnection正确映射到对应的ComM Channel;
- 使用AUTOSAR配置工具(如DaVinci Configurator)验证依赖关系。

秘籍:调试时可用CANalyzer观察NM报文是否在整个刷写期间持续发送。若中间断了几秒,基本可锁定为ComM配置错误。


❌ 坑点2:误唤醒频繁,静态电流超标

现象
车辆停放一夜后无法启动,测量发现蓄电池亏电严重。

排查结果
日志显示ECU平均每分钟被唤醒一次,但每次仅维持200ms便休眠。

根本原因
CAN硬件滤波器未启用,导致任意CAN帧(如仪表盘心跳)都会触发Wakeup中断。

对策
- 在CanIf中配置CanIfHthRef指向专用的Wakeup HTH(Hardware Transmit Handle);
- 设置仅响应特定ID范围(如0x7DF诊断请求、0x6xx NM帧);
- 启用“Filter Acceptance Range”或“Code/Mask”机制精确匹配。

经验法则:非关键节点建议采用“双级唤醒”策略——先由低成本MCU做初步过滤,确认是合法请求后再唤醒主控芯片。


❌ 坑点3:多主机竞争,网络无法休眠

场景
多个ECU同时支持远程诊断,某一节点唤醒后,其他节点也被带动上线,但彼此不知情,各自独立计时。

后果
A节点处理完诊断进入Prepare Sleep,但B节点仍在发NM报文,导致A无法真正休眠。

解决方案
- 使用统一的NM Network ID,确保所有相关节点属于同一个网络组;
- 配置合理的T_WaitBusSleep(推荐1.5~3s),留足协同窗口;
- 可引入“最后活动节点”机制,在BSW-M中统一裁决休眠时机。


工程最佳实践清单

项目推荐做法
📡 唤醒源控制仅允许诊断帧与NM帧触发Wakeup;关闭广播帧唤醒
🕐 NM报文周期200~500ms,兼顾延迟与负载;避免<100ms
🔗 ComM通道绑定Dcm必须关联正确的ComMChannel,否则保活无效
⏱️ 超时参数设置P2ServerMax ≥ 50msDiagMonitorTime ≈ 2×最大请求间隔
🧱 去抖动设计在Prepare Bus-Sleep阶段加入最小等待时间(≥2s)防抖动
🛠️ 调试手段开启CanNm和Dcm的日志输出;使用CANoe/CANalyzer抓包分析状态流
✅ 自检机制上电自检时验证CanNm与Dcm的接口连接性

写在最后:不只是CAN,更是未来通信协同的范式

今天我们聚焦的是CAN总线上的NM与UDS协作,但实际上,这种“事件驱动 + 状态同步 + 资源协同”的思想正在向更多领域延伸:

  • DoIP + Ethernet NM:在车载以太网中,同样存在WoL(Wake-on-LAN)、Sleep Mode Management等机制;
  • SOME/IP服务发现:服务提供者上线/下线也需要通知网络;
  • 中央计算架构:Zonal ECU需代理子设备的网络状态管理。

无论底层传输介质如何变化,如何在节能与响应之间取得平衡,始终是嵌入式系统的永恒命题。

而AUTOSAR给出的答案很清晰:分层解耦、事件驱动、集中决策、分布执行

掌握这套逻辑,不仅让你写出更稳健的节点控制代码,更能在未来SOA架构演进中游刃有余。


如果你正在开发一个支持远程诊断或OTA升级的ECU,不妨现在就去检查一下这几个问题:

  1. Dcm有没有正确调用ComM_Dcm_SetComStatus()
  2. ComM Channel是否绑定了Dcm的PDU通道?
  3. NM报文是否能在诊断期间持续发送?
  4. 休眠前是否有足够的防抖动时间?

一个小疏忽,可能就是那个让你熬夜三天还找不到的“偶发休眠bug”。

欢迎在评论区分享你的调试经历,我们一起排雷。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 16:27:44

Dify如何优化首字节时间?减少用户等待感知延迟

Dify如何优化首字节时间&#xff1f;减少用户等待感知延迟 在AI应用日益普及的今天&#xff0c;一个看似微小的技术指标——首字节时间&#xff08;Time to First Byte, TTFB&#xff09;&#xff0c;正悄然决定着用户是否愿意继续使用你的产品。哪怕模型能力再强、回答再精准&…

作者头像 李华
网站建设 2026/2/10 4:38:21

Figma中文界面本地化插件深度解析

Figma中文界面本地化插件深度解析 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma英文界面而烦恼&#xff1f;想要更高效地使用这款专业设计工具&#xff1f;Figma中文界面本…

作者头像 李华
网站建设 2026/2/3 5:55:36

突破传统:3个微信自动化场景的WeChatFerry实战指南

在即时通讯工具深度融入日常工作的今天&#xff0c;你是否曾因频繁的重复消息回复而苦恼&#xff1f;WeChatFerry作为一款专业的微信自动化工具&#xff0c;为技术爱好者提供了全新的解决方案。通过底层API对接技术&#xff0c;它让微信消息处理、联系人管理等操作变得简单高效…

作者头像 李华
网站建设 2026/2/4 15:12:30

构建高可用搜索平台:elasticsearch官网系统学习

构建高可用搜索平台&#xff1a;从 Elasticsearch 官网学起 在数据爆炸的今天&#xff0c;企业每天都在产生海量日志、用户行为和业务记录。无论是电商平台要实现毫秒级商品检索&#xff0c;还是运维团队需要实时监控系统异常&#xff0c; 快速、准确、稳定地从庞杂信息中捞出…

作者头像 李华
网站建设 2026/2/6 20:33:17

Windows HEIC缩略图终极解决方案:一键开启苹果照片预览功能

Windows HEIC缩略图终极解决方案&#xff1a;一键开启苹果照片预览功能 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 还在为Windows…

作者头像 李华