1. 从一次总线“假死”说起AUTOSAR网络管理到底在管什么如果你做过几年汽车电子大概率遇到过这种场景整车下电后某个ECU的电流迟迟降不下来或者反过来钥匙一拧某个节点死活不通信诊断仪连不上示波器一挂CAN总线上静悄悄。排查半天硬件没问题应用层逻辑也没问题最后发现是网络管理Network Management简称NM的状态机卡住了。AUTOSAR网络管理报文就是干这个的。它不传业务数据不传诊断专门负责一件事协调总线上各个节点什么时候一起睡、什么时候一起醒。你可以把它理解成一群人在一个房间里开会谁都不能单独走要走得大家一起走要留得大家一起留。NM报文就是大家互相喊话的“我还醒着”“我准备睡了”“再等一会儿”的信号。这篇笔记面向的是刚接触AUTOSAR CAN网络管理的嵌入式软件工程师、总线测试工程师以及需要配置CanNm模块的集成人员。我会从报文结构、状态机逻辑、配置参数、实操踩坑几个维度把CanNm这个东西讲透。不堆术语尽量用实际调试中会遇到的现象来解释背后的机制。关键词里出现了CanNm、NM、AUTOSAR、网络管理、报文这些核心词还有DaVinci Configurator、CANoe、CANape这些工具链说明大家关心的不只是理论更是怎么配、怎么测、怎么排错。那我们就按这个路子来。2. CanNm报文长什么样8个字节里藏着的协调逻辑2.1 标准帧格式与各字节含义CanNm报文使用标准CAN帧11位标识符DLC为8。标识符的分配在AUTOSAR规范里有推荐范围通常由OEM在通信矩阵中定义。比如大众系常用0x500到0x5FF这一段不同车型不一样但原则是NM报文的ID必须独立于应用报文和诊断报文且优先级要合理。8个字节的数据场AUTOSAR规范定义了明确的布局字节名称含义Byte 0Source Node Identifier源节点标识发送该NM报文的节点地址Byte 1Control Bit Vector控制位向量包含重复报文请求、NM协调关闭等标志Byte 2-7User Data用户数据可选通常用于传递唤醒原因或节点特定信息Byte 0的源节点标识在配置工具里对应CanNmPnInfo或CanNmNodeId参数。这个值必须全网唯一否则总线上的其他节点无法区分是谁在发NM报文。我见过有项目因为两个ECU配了同一个NodeId导致NM状态机行为异常排查了两天才定位到。Byte 1的控制位向量每一位都有讲究。Bit 0是Repeat Message Request当某个节点需要重新进入Repeat Message状态时会置位Bit 1是NM Coordinator Sleep Ready用于协调关闭场景Bit 4是Active Wakeup表示这个节点是主动唤醒源。这些位在CANoe的Trace窗口里可以直接解析出来前提是你加载了正确的NM数据库文件。Byte 2-7的用户数据AUTOSAR标准里没有强制定义但很多OEM会利用这几个字节传递额外信息。比如宝马在某些平台上用Byte 2表示唤醒原因是总线唤醒还是本地唤醒。这部分内容必须参照具体项目的通信矩阵不能想当然。2.2 NM报文与普通应用报文的关键差异很多人刚接触时会问NM报文和普通CAN报文到底有什么区别从物理层看没区别都是CAN帧。从协议层看区别在于发送逻辑和接收处理。普通应用报文的发送周期由应用层决定或者由COM模块按周期发送。NM报文的发送周期则由CanNm模块的状态机控制而且这个周期在总线睡眠过程中会动态变化。具体来说CanNm有三种发送周期Normal周期网络处于正常运行状态时的NM报文发送间隔通常配置为500ms或1000ms。Repeat Message周期节点刚唤醒或请求重复报文时的快速发送间隔通常配置为200ms。Ready Sleep周期节点准备进入睡眠但还在等待其他节点确认时的发送间隔通常与Normal周期一致或略长。这三个周期在DaVinci Configurator里的CanNmGlobalConfig容器下配置参数名分别是CanNmMsgCycleTime、CanNmMsgCycleOffset、CanNmRepeatMessageTime等。配置错了不会报错但总线行为会变得很奇怪比如所有节点都醒了但NM报文还在慢悠悠地发或者该睡的时候还在快速发。2.3 一个容易被忽略的细节NM报文的DLCAUTOSAR规范允许NM报文的DLC小于8但实际项目中几乎都用8。为什么因为CAN控制器在接收时如果DLC不匹配某些硬件会直接丢弃或者产生错误帧。更关键的是CANoe和CANape在解析NM报文时默认按8字节处理DLC不对会导致解析异常。我个人的建议是除非OEM通信矩阵明确要求否则NM报文一律用DLC8。用户数据用不到就填0x00或者0xFF不要省那几个字节。省出来的不是空间是麻烦。3. 状态机才是核心CanNm的五个状态与迁移条件3.1 五个状态的定义与实际表现CanNm模块的核心是一个状态机AUTOSAR规范定义了五个状态Bus Sleep Mode总线睡眠NM报文不发送模块处于低功耗状态。Prepare Bus Sleep Mode准备睡眠NM报文停止发送等待总线安静计时器超时。Network Mode网络模式包含三个子状态——Repeat Message、Normal Operation、Ready Sleep。Network Mode下的三个子状态才是日常调试中最常打交道的Repeat Message State节点刚唤醒或收到重复报文请求时进入快速发送NM报文同时启动RepeatMessageTimer。这个状态的目的是让总线上其他节点尽快感知到有新节点加入。Normal Operation StateRepeatMessageTimer超时后进入按Normal周期发送NM报文。只要节点还需要保持网络就停在这个状态。Ready Sleep State节点不再需要网络但还有其他节点在发NM报文时进入。此时停止发送NM报文但继续接收。如果收到NM报文说明还有别人需要网络就留在Ready Sleep如果NM报文超时说明大家都准备睡了就迁移到Prepare Bus Sleep。这三个子状态的迁移条件在CANoe里可以通过NM报文的变化直观看到。比如你强制某个节点进入Ready Sleep它的NM报文会停发但总线上其他节点的NM报文还在它的状态就停在Ready Sleep不动。3.2 状态迁移的触发条件与定时器状态迁移不是随便跳的每个迁移都有明确的触发条件。我把最关键的几个列出来当前状态触发条件目标状态Bus Sleep本地唤醒或收到NM报文Repeat MessageRepeat MessageRepeatMessageTimer超时Normal OperationNormal Operation网络请求释放Ready SleepReady Sleep收到NM报文Ready Sleep保持Ready SleepNM报文超时Prepare Bus SleepPrepare Bus SleepPrepareBusSleepTimer超时Bus Sleep这里面的定时器参数在DaVinci Configurator里对应CanNmRepeatMessageTimeRepeat Message状态的持续时间典型值1000ms到2000ms。CanNmTimeoutTimeNM报文接收超时时间典型值2000ms到5000ms。CanNmWaitBusSleepTimePrepare Bus Sleep状态的等待时间典型值1000ms到3000ms。这些参数不是拍脑袋定的要根据总线上节点数量、唤醒时间要求、电流消耗指标来综合计算。比如节点多、唤醒慢RepeatMessageTime就要适当加长如果整车静态电流要求严格WaitBusSleepTime就不能太长。3.3 实际调试中状态机卡死的三种典型情况第一种Repeat Message状态出不来。原因通常是RepeatMessageTimer没有正确启动或者CanNm_NetworkRequest没有被调用。检查CanNm模块的MainFunction是否被周期性调用以及CanNm_NetworkRequest的调用条件是否满足。第二种Ready Sleep状态收不到NM报文。这种情况往往是CanNmTimeoutTime配置过长或者CAN控制器的接收过滤器把NM报文过滤掉了。用CANoe挂上去看如果总线上明明有NM报文但节点没反应先查过滤器。第三种Prepare Bus Sleep状态反复跳回。这通常是因为某个节点在Prepare Bus Sleep期间又发了NM报文导致其他节点重新进入Repeat Message。排查方法是抓取完整的总线日志看是谁在“捣乱”。4. 配置实战DaVinci Configurator里CanNm的关键参数4.1 CanNmGlobalConfig容器下的必配项打开DaVinci Configurator找到CanNm模块第一个要配的就是CanNmGlobalConfig。这里面有几个参数是必须配的CanNmDevErrorDetect开发错误检测调试阶段打开量产关闭。CanNmMainFunctionPeriod主函数周期通常配5ms或10ms必须和BSW调度周期一致。CanNmNodeId本节点的NM报文源标识必须全网唯一。CanNmPnInfo部分网络信息如果项目用了Partial Network功能才需要配。CanNmMainFunctionPeriod这个参数特别容易配错。如果配成10ms但实际BSW调度是5msCanNm的状态机计时就会不准表现为NM报文发送周期忽快忽慢。我一般建议MainFunctionPeriod配成和BSW调度周期一致或者成整数倍关系。4.2 CanNmChannelConfig与CanNmRxPdu的关联CanNm模块支持多通道每个通道对应一个CAN控制器。在CanNmChannelConfig里需要关联CanNmRxPdu和CanNmTxPdu。CanNmRxPdu的配置里有一个关键参数CanNmRxPduId。这个ID必须和CanIf模块里的RxPduId对应上否则NM报文收不到。我见过一个项目CanIf里配了NM报文的接收但CanNmRxPduId填错了结果节点一直收不到NM报文状态机永远停在Ready Sleep最后总线睡不下去。CanNmTxPdu的配置相对简单主要是关联CanIf的TxPduId和确认回调。但要注意CanNmTxPdu的发送确认回调必须实现否则CanNm无法知道报文是否发送成功。4.3 定时器参数的工程计算方法定时器参数不能随便填我一般按下面的逻辑来算假设总线上有N个节点每个节点的NM报文发送周期为T_normal那么总线在Normal Operation状态下NM报文的平均间隔约为T_normal/N。CanNmTimeoutTime必须大于这个间隔的若干倍通常取3到5倍。举个例子N10T_normal500ms那么平均间隔50msTimeoutTime取2000ms是合理的。如果TimeoutTime取500ms那么只要有一个节点稍微延迟其他节点就会误判为超时导致状态机异常。WaitBusSleepTime的计算类似要保证在最后一个节点停止发送NM报文后所有节点都能在WaitBusSleepTime内完成状态迁移。如果节点多这个时间要适当加长。5. 测试与验证用CANoe和CANape抓NM报文5.1 CANoe里加载NM数据库与Trace解析CANoe是调试NM最常用的工具。要正确解析NM报文需要在CANoe工程里加载对应的NM数据库文件通常是.arxml或者.dbc格式。加载后Trace窗口会自动把NM报文的各个字段解析出来包括Source Node Id、Control Bit Vector、Repeat Message Request等。如果没有加载NM数据库Trace窗口只会显示原始字节你就得自己对着通信矩阵一个个查效率极低。我建议拿到通信矩阵后第一件事就是把NM报文定义导入CANoe。在CANoe的Trace窗口里可以设置过滤器只显示NM报文。具体操作是右键Trace窗口选择Filter在ID过滤里填入NM报文的ID范围。这样总线上其他报文就不会干扰你观察NM行为。5.2 用CANape观察NM状态机的实时变化CANape更适合观察NM状态机的内部变量。通过XCP或CCP协议可以把CanNm模块的内部状态变量映射到CANape的测量窗口里实时观察状态迁移。具体做法是在CANape工程里添加CanNm的状态变量比如CanNm_State、CanNm_RepeatMessageTimer、CanNm_TimeoutTimer等。然后触发一次唤醒观察这些变量随时间的变化。如果状态迁移不符合预期可以立刻定位到是哪个定时器出了问题。CANape的Trace窗口也可以记录NM报文但相比CANoeCANape更擅长和ECU内部变量联动分析。我一般用CANoe抓总线用CANape看内部状态两个工具配合使用。5.3 模拟发送NM报文的CAPL脚本有时候需要模拟某个节点发送NM报文验证其他节点的反应。用CAPL脚本可以轻松实现variables { msTimer t_NmSend; message 0x500 msg_Nm; } on start { msg_Nm.dlc 8; msg_Nm.byte(0) 0x01; // Source Node Id msg_Nm.byte(1) 0x00; // Control Bit Vector setTimer(t_NmSend, 500); } on timer t_NmSend { output(msg_Nm); setTimer(t_NmSend, 500); }这段脚本每500ms发送一帧NM报文源节点ID为0x01。你可以修改byte(1)的值来模拟Repeat Message Request或Active Wakeup。用这个脚本可以测试其他节点在收到NM报文后是否正确进入Repeat Message状态。注意模拟发送NM报文时源节点ID不能和总线上已有节点冲突否则会导致状态机混乱。6. 踩坑实录那些年CanNm配置翻过的车6.1 NodeId冲突导致的“幽灵唤醒”有一次项目调试整车下电后总线上偶尔会出现NM报文导致总线无法进入睡眠。排查了很久最后发现是两个ECU的CanNmNodeId配成了同一个值。当其中一个节点进入Ready Sleep停止发送后另一个节点还在发但源节点ID相同其他节点以为是同一个节点在发状态机就混乱了。这个问题的隐蔽性在于NodeId冲突不会导致通信失败只会导致状态机行为异常。总线上的NM报文看起来正常但状态迁移就是不对。后来我们在CANoe里加了源节点ID的统计才发现有两个节点用了同一个ID。教训配置完成后一定要用脚本或人工检查所有节点的NodeId是否唯一。6.2 MainFunction周期不一致引发的定时器漂移另一个坑是CanNmMainFunctionPeriod和BSW调度周期不一致。有个项目里CanNm的MainFunctionPeriod配了10ms但BSW实际调度是7.5ms。结果CanNm的定时器全部偏慢RepeatMessageTime实际变成了1333ms而不是1000ms导致总线唤醒时间比预期长了300多ms。这个问题在实验室里不容易发现因为实验室通常只关注功能是否正常不关注时间精度。但到了整车测试唤醒时间超标就会被判不合格。教训MainFunctionPeriod必须和BSW调度周期严格一致配置完成后用示波器或CANoe测量实际NM报文周期来验证。6.3 接收过滤器把NM报文挡在门外CanIf模块的接收过滤器配置错误也会导致NM报文收不到。有个项目里CanIf的RxPdu配置了NM报文的ID但CanController的接收过滤器只允许应用报文通过NM报文被硬件过滤掉了。结果就是节点能发NM报文但收不到别人的NM报文状态机永远停在Ready Sleep。这个问题的排查方法是用CANoe确认总线上有NM报文然后检查ECU的CAN控制器接收过滤器配置。如果过滤器是硬件层面的软件里看不到需要用CANape或调试器读取CAN控制器的寄存器。教训接收过滤器的配置要覆盖所有需要接收的报文ID包括NM报文和诊断报文。7. 从CanNm到整车网络管理还需要知道的事7.1 NM协调关闭与部分网络CanNm只是AUTOSAR网络管理的一部分。在更复杂的整车架构里还会用到Nm协调关闭NM Coordinator和部分网络Partial NetworkPN。NM协调关闭是指当整车需要下电时由某个主节点协调所有节点一起进入睡眠。这个主节点通常是网关或者BCM。协调关闭的逻辑在Nm模块里实现CanNm只是执行层。部分网络是指总线上某些节点可以独立于其他节点进入睡眠而不影响其他节点。这个功能在CanNm里通过CanNmPnInfo和CanNmPnResetTime实现。部分网络的配置比普通NM复杂得多需要仔细规划每个节点的PN信息。7.2 CanNm与ComM、EcuM的交互CanNm不是孤立工作的它和ComM、EcuM模块有紧密的交互ComM通信管理器负责协调CanNm、CanSM、Com等模块。ComM_RequestComMode会触发CanNm_NetworkRequestComM_ReleaseComMode会触发CanNm_NetworkRelease。EcuMECU状态管理器负责管理ECU的唤醒和睡眠。EcuM_StartWakeupSources会触发CanNm的唤醒流程EcuM_GoDown会触发CanNm进入Prepare Bus Sleep。理解这些交互关系才能在调试时快速定位问题。比如总线睡不下去可能是ComM没有释放也可能是EcuM没有触发睡眠流程不一定是CanNm本身的问题。7.3 不同OEM的NM规范差异AUTOSAR规范只是框架具体到每个OEMNM的实现细节会有差异。比如大众的NM报文ID范围和字节定义有自己的规范。宝马的NM报文里会传递唤醒原因。吉利的NM规范里对RepeatMessageTime有特殊要求。做项目时一定要拿到OEM的NM规范文档不能只看AUTOSAR标准。我见过有人照着AUTOSAR标准配了一通结果和OEM规范对不上返工重来。8. 个人经验CanNm调试的几条实用建议调试CanNm这么多年我总结了几条实用的建议都是踩坑踩出来的第一先抓总线再查代码。遇到NM相关问题第一反应应该是用CANoe抓总线看NM报文的发送和接收是否正常。总线上的信息比代码里的逻辑更直接。第二配置完成后做一次全节点NodeId检查。写个简单的脚本把所有节点的CanNmNodeId读出来确认没有重复。这个检查花不了几分钟但能避免很多诡异问题。第三定时器参数留有余量。TimeoutTime和WaitBusSleepTime不要卡得太紧留20%到30%的余量。总线负载高的时候NM报文的延迟可能比你想象的大。第四用CANape观察内部状态变量。总线上的NM报文只能告诉你“发生了什么”内部状态变量才能告诉你“为什么发生”。把CanNm_State、CanNm_RepeatMessageTimer这些变量映射到CANape里调试效率会高很多。第五不同OEM的规范要分开管理。如果同时做多个OEM的项目建议把每个OEM的NM规范单独整理成配置模板避免混淆。大众的配置不能直接套到吉利上字节定义可能完全不一样。最后说一个我最近遇到的案例有个项目在整车下电后某个ECU的NM报文会多发一帧才停。查了半天发现是CanNmTxPdu的发送确认回调里没有正确处理发送失败的情况导致状态机以为报文没发出去又重发了一次。这个问题的根源不在CanNm配置而在CanIf的发送确认逻辑。所以NM问题不一定在NM模块里要顺着调用链往上查。
企业数字化 ERP 产品动态
相关推荐
7-Zip实战指南:提升压缩率、加密分卷与命令行批量处理 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:08:17
Word导出带目录全攻略:从域原理到程序化生成与PDF跳转 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:08:17
边缘端AI芯片选型:从场景反推算力与功耗的实战方法论 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:08:11
C#上位机温室监控系统实战:串口通信与Modbus RTU开发指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:49:38
BMS绝缘检测原理与工程实践:不平衡电桥从推导到量产落地 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:49:38
高精度电流检测电路设计:从采样电阻到PCB布局全链路实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:49:38
宽带阶梯阻抗变换器8步设计法:从切比雪夫综合到ADS仿真 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:49:38
RabbitMQ测试工具实战:从Docker部署到命令行判活与消息收发自测 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:49:37
纯旁路准入实战:SNMP+混合式技术替代802.1x的军工涉密网部署指南 简介:这份文档面向军工行业信息化建设者、涉密网络运维人员及网络安全方案选型者,以中航工业集团某所内网准入改造为实例,梳理涉密网络环境下终端接入管控的完整落地思路。资源包共1个docx文件,约17KB,内容围绕客户背景… · 2026/9/25 1:49:31
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37