一、先一句话理解:CanNm 是干嘛的?

最短定义

CanNm = 管 CAN 网络“大家什么时候醒、什么时候睡”的模块。

它的核心任务不是发业务报文,而是:

  • 协调整个 CAN 网络上的节点
  • 判断网络要不要保持唤醒
  • 判断什么时候可以进入休眠
  • 通过发送/接收 NM 报文(Network Management PDU) 来让所有节点达成一致

二、先用生活化比喻理解 CanNm

你可以把一个 CAN 网络想成一个群聊,群里有很多 ECU 节点。

CanNm 做的事像什么?

像群成员每隔一段时间发一句:

“我还醒着,我还需要这个群别关。”

这句话就是 NM 报文


整个网络什么时候保持唤醒?

只要群里还有人持续发“我还醒着”,那大家就知道:

  • 网络还要保持活动
  • 不能睡

什么时候睡?

当某个节点不再需要通信,它就不再发 NM 报文
但只要它还收到别人发的 NM 报文,它就会继续等。

直到:

一段时间内,谁都不再发 NM 报文了

那所有节点就认为:

  • 大家都准备睡了
  • 可以进入 Bus Sleep

谁唤醒网络?

任何一个节点只要突然又有通信需求,就可以:

  • 请求网络
  • 再发 NM 报文
  • 让大家重新进入工作状态

三、CanNm 和 CanSM 到底有什么区别?

这个是初学者最容易混的点,我给你直接分开。


1)CanNm 关注的是“网络管理协议”

它管的是:

  • 网络是否要保持唤醒
  • 节点之间如何通过 NM 报文达成睡眠/唤醒共识
  • 网络管理状态机怎么跑

一句话:

CanNm 管“大家商量好什么时候睡/醒”。


2)CanSM 关注的是“CAN 硬件网络状态切换”

它管的是:

  • Controller STARTED / STOPPED / SLEEP
  • Transceiver NORMAL / STANDBY
  • PDU Mode ONLINE / TX_OFFLINE
  • Bus-Off 恢复

一句话:

CanSM 管“商量完之后,硬件怎么真正切状态”。


3)用一句对比记住

  • CanNm:协议层的“商量睡觉”
  • CanSM:状态管理层的“真的去关灯/开灯”

四、CanNm 在 AUTOSAR 里的位置

根据文档,它主要关系是:

text复制代码

上层(Nm / ComM)
       ↓
     CanNm
       ↓
     LSduR
       ↓
  下层(例如 CanIf)

另外它还会和这些模块交互:

  • Nm:统一 Network Management 接口层
  • ComM:通信管理模块
  • LSduR:往下发 PDU 的路由模块
  • CanIf:实际 CAN 接口层(通过 LSduR 间接到达)
  • PduR:如果用 COM User Data 支持
  • CanSM:部分网络下,CanNm 会在 TX 超时异常时通知 CanSM 恢复
  • DET:开发/运行时错误上报

五、CanNm 的核心思想:去中心化管理

文档 7.1 讲得很明确:

CanNm 基于 decentralized direct network management strategy
也就是 去中心化、分布式的直接网络管理


这是什么意思?

不是网络里有一个“唯一大脑”统一指挥所有节点。
而是:

  • 每个节点都自己跑 CanNm 状态机
  • 每个节点都根据自己发出的和收到的 NM 报文来判断当前网络状态
  • 大家遵守同一套规则,就能同步地醒和睡

所以 CanNm 的关键输入是什么?

不是复杂的上层命令,而是:

  1. 我自己有没有请求网络
  2. 我有没有收到别人的 NM 报文
  3. 定时器有没有超时
  4. 某些控制位(CBV bits)有没有被设置

六、你必须先记住的 3 个“操作模式”

CanNm 对外可见的操作模式有 3 个:

文档 7.2 明确写了:

  • Network Mode
  • Prepare Bus-Sleep Mode
  • Bus-Sleep Mode

1)Network Mode

这是网络正常工作的模式。
意味着:

  • 网络是活的
  • 节点处于参与网络管理的状态
  • 可能会发送 NM 报文

2)Prepare Bus-Sleep Mode

这是“准备睡觉”的过渡模式。

作用是:

  • 给所有节点一点时间做收尾
  • 让总线上的活动慢慢停下来
  • 等待 Tx buffer 清空
  • 最终再进入真正的 Bus-Sleep

3)Bus-Sleep Mode

这是睡眠模式。

作用是:

  • 降低功耗
  • 通信控制器进入睡眠
  • 激活必要的唤醒机制
  • 网络不再活跃

七、Network Mode 里面还有 3 个内部状态

这个是 CanNm 最核心的状态机结构。

文档 7.2.1 说:

Network Mode 内部包含 3 个状态:

  • Repeat Message State
  • Normal Operation State
  • Ready Sleep State

你先把它理解成“工作模式里的 3 个阶段”。


八、先给你一张“超简化状态图”


CanNm 学习版主状态图

text复制代码

上电初始化
   ↓
[Bus-Sleep Mode]
   │
   ├── PassiveStartUp / NetworkRequest
   ↓
[Network Mode]
   │
   ├── 默认先进入
   ↓
[Repeat Message State]
   │
   ├── 如果网络仍被请求
   ↓
[Normal Operation State]
   │
   ├── 如果本节点释放网络
   ↓
[Ready Sleep State]
   │
   ├── 如果一段时间没人再发NM报文
   ↓
[Prepare Bus-Sleep Mode]
   │
   ├── 等待 calm down / wait bus sleep
   ↓
[Bus-Sleep Mode]

同时还有几条反向路径:

text复制代码

Ready Sleep State
   ├── 如果又请求网络 → 回 Normal Operation
   ├── 如果收到 Repeat Message Request → 回 Repeat Message

Prepare Bus-Sleep Mode
   ├── 收到 NM 报文 → 回 Network Mode(Repeat)
   ├── 请求网络 → 回 Network Mode(Repeat)

Bus-Sleep Mode
   ├── PassiveStartUp → 回 Network Mode(Repeat)
   ├── NetworkRequest → 回 Network Mode(Repeat)
   └── 收到 NM 报文 → 通知上层有节点启动了(但不自动直接切换)

九、逐个状态讲人话


1)Bus-Sleep Mode:已经睡着了

这是初始化后的默认模式。

文档 7.4 明确说:

  • CanNm_Init 成功后,CanNm 默认进入 Bus-Sleep Mode
  • 默认网络状态是 released

也就是:

text复制代码

刚初始化完成 = 还没人说要通信 = 先当作睡着

2)Prepare Bus-Sleep Mode:准备睡

这个模式的作用不是立刻睡,而是:

  • 让网络平静下来
  • 等待还在路上的报文发完
  • 再真正进入 Bus-Sleep

它就像“下班前收拾工位”。


3)Repeat Message State:刚醒来时先多喊几声

这个状态非常关键。

文档说它的作用包括:

  • 让其它节点明确看到“我起来了”
  • 保证节点至少保持活跃一段时间
  • 可用于 Node Detection

通俗理解

刚启动/刚唤醒时,不是只发一次“我醒了”,而是会在一段时间内重复发 NM 报文。

所以你可以理解为:

Repeat Message State = 刚进入网络时的“高可见度广播阶段”


4)Normal Operation State:正常工作中

这是最稳定、最常见的状态。

特点:

  • 网络已被请求
  • 周期性发 NM 报文
  • 网络保持唤醒
  • 只要还需要通信,就待在这里

5)Ready Sleep State:我不想说话了,但先等等别人

这是一个非常重要、非常容易误解的状态。

它不是睡了,而是:

  • 我自己已经不再请求网络了
  • 所以我停止主动发 NM 报文
  • 但我还会继续观察别人
  • 只要别人还在发,我就先不睡

通俗理解

像你已经下班了,但同事还在加班。
你虽然不干活了,但你也不会马上锁门走人。


十、CanNm 的“并行状态”:requested / released

这个点很重要,文档 7.3 专门讲了。

CanNm 除了主状态机以外,还有一个并行概念

  • network requested
  • network released

requested 是什么意思?

表示:

本 ECU 还需要这个网络,要通信。

通过 CanNm_NetworkRequest() 设置。


released 是什么意思?

表示:

本 ECU 自己不再需要通信了。

通过 CanNm_NetworkRelease() 设置。


最容易误解的点

released 不等于马上睡。

因为:

  • 虽然你自己不需要通信了
  • 但如果别的 ECU 还在请求网络
  • 它们还在发 NM 报文
  • 你仍可能停留在 Network Mode / Ready Sleep 等状态

所以你要记住:

requested / released 只是“我自己要不要通信”的意愿,不等于整个网络马上切模式。


十一、CanNm 的核心运行逻辑

文档 7.1 讲得非常清楚,我帮你翻译成简单步骤。


核心规则 1:发 NM 报文 = “我还想保持网络醒着”

只要某节点还在发 NM 报文,别的节点就知道:

  • 这个节点还活跃
  • 网络不能睡

核心规则 2:停止发 NM 报文 = “我自己准备睡了”

某节点如果准备睡,就不再发 NM 报文。

但是它还会继续监听。


核心规则 3:只要还能收到别人发的 NM 报文,就继续等

哪怕我自己已经 release 了网络,但我只要还不断收到别人的 NM 报文,就说明别人还没睡,我也不能睡。


核心规则 4:一段时间内再也没收到 NM 报文,才进入睡眠流程

如果 NM-Timeout Timer 超时了,说明:

  • 总线上已经没有节点在宣告“我还醒着”
  • 所有人都差不多准备睡了

这时就进入睡眠方向的状态迁移。


十二、你一定要理解的几个定时器

CanNm 本质上是一个状态机 + 多个定时器的组合。
不懂定时器,就很难真懂 CanNm。


1)NM-Timeout Timer

这是最核心的定时器。

作用

用于判断:

还有没有节点在继续发 NM 报文保持网络唤醒?

什么时候重启?

文档说在 Network Mode 里:

  • 成功接收到 NM 报文时重启
  • 成功发送 NM 报文确认时也重启

超时后会怎样?

取决于当前状态:

  • 在 Ready Sleep State 超时 → 进入 Prepare Bus-Sleep Mode
  • 在 Repeat / Normal 里异常超时 → 可能报运行时错误 CANNM_E_NETWORK_TIMEOUT

2)Repeat Message Timer

作用

决定在 Repeat Message State 要待多久。

配置参数:

  • CanNmRepeatMessageTime

超时后去哪里?

  • 如果网络还是 requested → 去 Normal Operation State
  • 如果网络已经 released → 去 Ready Sleep State

3)Message Cycle Timer

作用

控制 NM 报文的周期性发送。

配置参数主要是:

  • CanNmMsgCycleTime
  • CanNmMsgCycleOffset
  • CanNmImmediateNmCycleTime

4)Wait Bus-Sleep Timer

作用

控制在 Prepare Bus-Sleep Mode 要等多久,才真正进入 Bus-Sleep Mode。

配置参数:

  • CanNmWaitBusSleepTime

5)Remote Sleep Indication Timer

作用

用于判断:

其它 ECU 是否都已经准备睡觉了?

配置参数:

  • CanNmRemoteSleepIndTime

6)NM Message Tx Timeout Timer

作用

主要用于 Partial Networking 场景下,监控 NM 报文发送是否超时没成功确认。

配置参数:

  • CanNmMsgTimeoutTime

如果超时,会触发:

  • Nm_TxTimeoutException()
  • 还可能进一步通知 CanSM_TxTimeoutException()

十三、CanNm 的主流程怎么学?

我建议你把主流程分成 4 条主线。


主线 1:启动网络流程

1)Bus-Sleep / Prepare Bus-Sleep → Network Mode

触发方式有两个:

  • CanNm_PassiveStartUp()
  • CanNm_NetworkRequest()

进入 Network Mode 后,文档要求默认先进入:

  • Repeat Message State

为什么不是直接进 Normal?

因为刚醒来时,要先通过 Repeat Message 让全网明确看到:

“我回来了,网络要重新活跃起来了。”


主线 2:正常保持网络唤醒

2)Repeat Message → Normal Operation

在 Repeat Message State 待满 CanNmRepeatMessageTime 后:

  • 如果 network = requested → 进入 Normal Operation State
  • 如果 network = released → 进入 Ready Sleep State

Normal Operation State 的本质就是:

  • 持续发 NM 报文
  • 保持网络清醒

主线 3:释放网络并准备睡眠

3)Normal Operation → Ready Sleep

当调用 CanNm_NetworkRelease() 后,本节点网络状态变成 released
如果当前在 Normal Operation State,则进入:

  • Ready Sleep State

Ready Sleep State 做什么?

  • 停止发送 NM 报文
  • 但继续监听别人发的 NM 报文
  • 只要还收到别人发,就继续等

4)Ready Sleep → Prepare Bus-Sleep

当 NM-Timeout Timer 在 Ready Sleep State 超时,说明:

  • 很久没人再发 NM 报文了
  • 大家应该都不再需要网络了

于是进入:

  • Prepare Bus-Sleep Mode

5)Prepare Bus-Sleep → Bus-Sleep

在 Prepare Bus-Sleep Mode 再等待:

  • CanNmWaitBusSleepTime

之后进入:

  • Bus-Sleep Mode

主线 4:睡着后被唤醒

6)Bus-Sleep 里收到 NM 报文会怎样?

这是一个很重要的细节。

文档明确说:

  • 在 Bus-Sleep Mode 收到 NM 报文
  • CanNm 不会自动直接切回 Network Mode
  • 它只会通知上层:
    • Nm_NetworkStartIndication()

为什么?

因为要避免 race condition 和 ECU 启停状态不一致。

所以你要记住一句话:

Bus-Sleep 下收到 NM 报文,不等于 CanNm 自己直接醒;它先告诉上层“有人启动了”,由上层决定后续动作。

这是很容易被问的点。


十四、Repeat Message State 为什么这么重要?

你可以把 Repeat Message State 当成 CanNm 的“启动广播模式”。


它的作用有 3 个

1. 刚启动时让别人看见我

如果没有这个状态,节点醒来后可能只发一条或太少条 NM 报文,别的 ECU 可能没及时感知到。


2. 保证至少活跃一小段时间

这能避免网络刚醒又马上睡,造成系统不稳定。


3. 可用于 Node Detection

如果启用了 Node Detection,这个阶段可以帮助识别网络上有哪些节点在线。


十五、CanNm 报文(NM PDU)长什么样?

文档 7.6 讲了 NM PDU 结构。

最常见要认识的字段有:

  • SNI:Source Node Identifier,源节点 ID
  • CBV:Control Bit Vector,控制位向量
  • User Data
  • PNC Bit Vector(如果启用 PN)

一个典型 8 字节示例

例如:

  • Byte0 = SNI
  • Byte1 = CBV
  • 中间若干字节 = User Data
  • 后面若干字节 = PNC Bit Vector

但注意:

SNI 和 CBV 的位置是可配置的,可以在 Byte0、Byte1,甚至可以 off。


十六、CBV(控制位向量)是 CanNm 的灵魂

文档给了 Control Bit Vector 的位定义。
你不用一口气全背,但要先认识最重要的几个 bit。


1)Repeat Message Request Bit

表示:

请求所有节点重新进入/重进 Repeat Message State

这个很关键。


2)Active Wakeup Bit

表示:

这次进入 Network Mode 是因为主动唤醒(active wakeup)

也就是本节点主动请求网络而醒来。


3)NM Coordinator Sleep Ready Bit

用于协调器同步场景下表示:

协调器已经准备进入睡眠协调流程


4)PNI(Partial Network Information)Bit

表示:

这个 NM 报文里带了 Partial Networking 信息


5)Partial Network Learning Bit

用于 PNC 学习场景。


6)PNSR(PN Shutdown Request)Bit

表示:

这是一个 PN shutdown message

也就是同步 PNC shutdown 的控制信号。


十七、CanNm 是怎么发 NM 报文的?

文档 7.7.1 说,CanNm 支持两种主要发送模式:

  • Periodic transmission mode
  • Periodic transmission mode with bus load reduction

1)普通周期发送

最容易理解:

每隔固定周期发一条 NM 报文

核心参数:

  • CanNmMsgCycleTime
  • CanNmMsgCycleOffset

2)刚醒来时的立即发送

如果配置允许,在主动唤醒后可以:

  • 立即发第一条 NM 报文
  • 然后再按 CanNmImmediateNmCycleTime 连发几条
  • 连发数量由 CanNmImmediateNmTransmissions 决定

通俗理解

刚醒来先“吼几声”:

“大家注意,我醒了,我真的醒了,我要保持网络活跃!”


十八、什么是 Bus Load Reduction(总线负载降低机制)?

这个是 CanNm 的经典特点之一。


不开这个会怎样?

假设总线上有很多节点,每个节点都固定周期发 NM 报文,那总线会很忙。


开了之后怎么优化?

文档的核心思想是:

  • 收到别人的 NM 报文后,不一定按原始大周期发
  • 可以用一个更短但带节点差异的 CanNmMsgReducedTime 重装发送定时器
  • 最终效果是:

实际上只有少数几个“最早到点”的节点交替发 NM 报文
其余节点就被“压住”了


最终效果

文档说明:

总线负载可以被限制到最多每个 CanNmMsgCycleTime 只有大约 2 条 NM 报文


一句话理解

Bus Load Reduction 就是:

大家没必要都一直喊“我醒着”,挑少数几个代表轮流喊就够了。


十九、Remote Sleep Indication 是什么?

这个功能是:

我虽然还在 Normal Operation,但我想知道“是不是别人都已经准备睡了?”


触发条件

如果启用了 CanNmRemoteSleepIndEnabled,并且:

  • 在 Normal Operation State
  • 一段时间没收到 NM 报文
  • 时间达到 CanNmRemoteSleepIndTime

CanNm 就会通知上层:

  • Nm_RemoteSleepIndication()

表示:

其它节点应该都准备睡了。


取消条件

如果之后又收到 NM 报文,或者重新进入 Repeat Message State,则调用:

  • Nm_RemoteSleepCancellation()

表示:

不行,还有人没准备睡。


二十、Passive Mode 是什么?

Passive Mode 很好理解。

文档说:

Passive Mode 下,节点只接收 NM 报文,不发送 NM 报文。


通俗解释

就是:

text复制代码

我参加群,但我只看不发言

适合什么场景?

适合某些节点不希望参与 cluster shutdown 决策,只想被动跟随网络状态。


二十一、Communication Control 是什么?

这是 CanNm 的一个可选特性。

API 有:

  • CanNm_DisableCommunication()
  • CanNm_EnableCommunication()

它控制的是什么?

注意,不是整个 CanNm 关掉。

它控制的是:

NM PDU transmission ability
也就是 NM 报文发送能力


DisableCommunication 后会怎样?

文档说会:

  • 禁止 NM PDU 发送
  • 停止 Message Cycle Timer
  • 停止 NM-Timeout Timer
  • 停止 Remote Sleep 检测

EnableCommunication 后会怎样?

重新允许发送,并且:

  • 最晚下一次 MainFunction 开始重新发送
  • 重启 NM-Timeout Timer
  • 重启 Remote Sleep 检测(如启用)

二十二、User Data 是什么?

CanNm 的 NM 报文里可以有一块用户数据区。


作用

可以在 NM 报文里携带一些附加信息。

CanNm 支持两种访问方式:

1. 直接 API 方式

  • CanNm_SetUserData()
  • CanNm_GetUserData()

2. COM/PduR 方式

如果开启 CanNmComUserDataSupport,则用户数据由 COM 路径提供。


注意

如果开启了 CanNmComUserDataSupport

  • CanNm_SetUserData() 不再提供

二十三、Partial Networking(PN)是什么?

这个是 CanNm 的进阶重点,但我先给你用通俗方式解释。


没有 PN 时

一个 CAN 网络上的节点基本是“一起醒、一起睡”。


有 PN 时

可以把网络按“局部功能簇”来区分,只有和某个功能簇相关的 ECU 需要保持唤醒,其它 ECU 不一定要一直全开。


CanNm 在 PN 下做什么?

CanNm 会处理:

  • PNI bit
  • PNC bit vector
  • 相关 PNC 请求是否和本 ECU 有关
  • 不相关的 NM 报文可直接忽略
  • 相关的才继续标准处理

最关键的一句话

PN 的本质是:不是每条 NM 报文都值得让所有 ECU 一直醒着。


二十四、CanNm 对 PN 报文怎么过滤?

文档 7.11.1 很关键。


如果 CanNmPnEnabled = FALSE

那就:

  • 不做 PN 扩展处理
  • 不丢 NM 报文
  • 按普通 NM 报文处理

如果 CanNmPnEnabled = TRUE 且收到的 PNI = 0

分两种情况:

情况 A:CanNmAllNmMessagesKeepAwake = TRUE

  • 不丢
  • 继续按普通 NM 报文处理
  • 只是忽略 PN 扩展

情况 B:CanNmAllNmMessagesKeepAwake = FALSE

  • 直接忽略该 NM 报文

如果 CanNmPnEnabled = TRUE 且 PNI = 1

那 CanNm 会提取 PNC bit vector,并交给上层判断:

  • 有没有相关 PNC 请求
  • 是否值得继续保持 ECU 唤醒

二十五、CanNm 和 CanSM 在 TX Timeout 上怎么联动?

文档 7.12 明确说:

在一些场景下(尤其 PN 下):

  • CanNm 会监控 NM 报文发送确认是否超时
  • 如果超时,会调用:
    • Nm_TxTimeoutException()
    • 还可能调用 CanSM_TxTimeoutException()

为什么要告诉 CanSM?

因为 CanNm 只是发现:

“我这个 NM 报文发不出去,可能底层网络状态出问题了。”

真正的恢复动作,往往需要 CanSM 去做,比如重新恢复网络状态。


二十六、CanNm 最常用 API 怎么记?


1)CanNm_Init()

初始化 CanNm。

初始化后默认:

  • mode = Bus-Sleep
  • network state = released

2)CanNm_DeInit()

反初始化 CanNm。
要求所有网络都已经在 Bus-Sleep Mode。


3)CanNm_PassiveStartUp(channel)

从 Bus-Sleep / Prepare Bus-Sleep 进入 Network Mode(Repeat Message State),但不一定表示主动请求网络。


4)CanNm_NetworkRequest(channel)

请求网络。
会把 network state 变成 requested

这是“我要保持网络醒着”的核心接口。


5)CanNm_NetworkRelease(channel)

释放网络。
会把 network state 变成 released


6)CanNm_DisableCommunication(channel)

禁止 NM PDU 发送能力。


7)CanNm_EnableCommunication(channel)

恢复 NM PDU 发送能力。


8)CanNm_SetUserData(channel, ptr)

设置下一次发送 NM 报文的用户数据。


9)CanNm_GetUserData(channel, ptr)

读取最近收到的 NM 报文中的用户数据。


10)CanNm_GetNodeIdentifier(channel, ptr)

读最近收到的 NM 报文的源节点 ID。


11)CanNm_GetLocalNodeIdentifier(channel, ptr)

读本地配置的节点 ID。


12)CanNm_RepeatMessageRequest(channel)

请求设置 Repeat Message Request Bit。


13)CanNm_GetPduData(channel, ptr)

读取最近收到的完整 NM PDU。


14)CanNm_GetState(channel, &state, &mode)

读取当前状态和模式。


15)CanNm_RequestBusSynchronization(channel)

请求发送一条单次 NM 报文,用于 bus synchronization。


16)CanNm_CheckRemoteSleepIndication(channel, &flag)

查询是否已经检测到 Remote Sleep Indication。


17)CanNm_SetSleepReadyBit(channel, bit)

设置 NM Coordinator Sleep Ready bit。


18)CanNm_PnLearningRequest(channel)

请求进入 Partial Network Learning 流程。


19)CanNm_ActivateTxPnShutdownMsg(channel)

激活发送 PN shutdown message。


20)CanNm_DeactivateTxPnShutdownMsg(channel)

取消发送 PN shutdown message。


二十七、CanNm 的回调有哪些?


1)CanNm_RxIndication()

下层收到 NM 报文时通知 CanNm。


2)CanNm_TxConfirmation()

下层通知 CanNm:NM 报文发送成功或失败。


3)CanNm_TriggerTransmit()

下层需要 CanNm 提供即将发送的 NM PDU 内容时调用。


4)CanNm_ConfirmPnAvailability()

启用 PN filter 功能。


二十八、CanNm 的关键配置参数,初学者先抓这些

配置很多,你先抓最重要的。


A. 全局开关类

1)CanNmPassiveModeEnabled

是否启用 Passive Mode。


2)CanNmBusLoadReductionEnabled

是否全局支持总线负载降低。


3)CanNmRemoteSleepIndEnabled

是否启用 Remote Sleep Indication。


4)CanNmComControlEnabled

是否支持 Communication Control。


5)CanNmCoordinatorSyncSupport

是否支持协调器同步。


6)CanNmGlobalPnSupport

是否全局支持 Partial Networking。


7)CanNmImmediateRestartEnabled

是否支持 Prepare Bus-Sleep 时的立即重启发送。


8)CanNmImmediateTxconfEnabled

是否把每次发送请求都视为立即确认成功。


9)CanNmUserDataEnabled

是否支持用户数据。


10)CanNmComUserDataSupport

是否通过 COM/PduR 支持用户数据路径。


B. 每个通道最重要的时间参数

1)CanNmMsgCycleTime

NM 报文周期发送时间。


2)CanNmMsgCycleOffset

进入周期发送时的初始偏移时间。


3)CanNmRepeatMessageTime

Repeat Message State 持续时间。


4)CanNmTimeoutTime

NM Timeout 时间。
在 Ready Sleep 下决定何时进入 Prepare Bus-Sleep;在某些运行状态异常超时会触发错误。


5)CanNmWaitBusSleepTime

Prepare Bus-Sleep 停留时间。


6)CanNmRemoteSleepIndTime

检测 Remote Sleep 的时间。


7)CanNmImmediateNmTransmissions

立即发送的 NM 报文条数。


8)CanNmImmediateNmCycleTime

立即发送阶段的报文周期。


9)CanNmMsgReducedTime

Bus Load Reduction 下的节点特定发送周期。


10)CanNmMsgTimeoutTime

PN 场景下 NM 报文发送确认超时监控时间。


C. PDU 结构相关参数

1)CanNmPduNidPosition

SNI 在 PDU 的哪个字节。


2)CanNmPduCbvPosition

CBV 在 PDU 的哪个字节。


3)CanNmNodeId

本地节点 ID。


4)CanNmPnEnabled

该通道是否启用 PN。


二十九、CanNm 的错误分类怎么记?

文档 7.14 给了错误分类。


1)开发错误

常见有:

  • CANNM_E_UNINIT
  • CANNM_E_INVALID_CHANNEL
  • CANNM_E_INVALID_PDUID
  • CANNM_E_INIT_FAILED
  • CANNM_E_PARAM_POINTER
  • CANNM_E_NOT_IN_BUS_SLEEP

2)运行时错误

重点记 3 个:

CANNM_E_NET_START_IND

在 Bus-Sleep Mode 下收到了 NM PDU。


CANNM_E_NETWORK_TIMEOUT

NM-Timeout Timer 在不该异常超时的地方超时了。


CANNM_E_INVALID_PN_SYNC_SHUTDOWN_REQUEST

在不允许的 actively coordinated 通道上收到了带 PNSR 的 NM 报文。


三十、你最容易混淆的点,我提前帮你拆掉


1)CanNm 不负责 Controller 模式切换

那是 CanSM 的事。


2)requested/released 不是主模式

它只是并行的“网络意愿状态”。


3)Ready Sleep 不是已经睡了

它只是:

我先不发了,但还等别人。


4)Bus-Sleep 收到 NM 报文,不是 CanNm 自动直接回 Network Mode

它先通知:

  • Nm_NetworkStartIndication()

让上层决定后续。


5)Repeat Message State 很关键,不是可有可无

它负责:

  • 刚唤醒时广播存在感
  • 启动稳定性
  • 节点检测支持

6)Communication Control 禁的是“NM 报文发送能力”

不是把整个 CanNm 逻辑彻底关死。


三十一、我建议你的学习顺序


第 1 步:只回答“CanNm 是干嘛的”

先能说清:

CanNm 通过周期性 NM 报文,在 CAN 网络节点之间协调网络保持唤醒还是进入 Bus-Sleep。


第 2 步:背 3 个模式 + 3 个内部状态

模式:

  • Network Mode
  • Prepare Bus-Sleep Mode
  • Bus-Sleep Mode

内部状态:

  • Repeat Message State
  • Normal Operation State
  • Ready Sleep State

第 3 步:背 4 条主线流程

  1. 启动网络:BusSleep → Repeat → Normal
  2. 释放网络:Normal → ReadySleep
  3. 睡眠流程:ReadySleep → PrepareBusSleep → BusSleep
  4. 收到启动迹象:BusSleep 收到 NM PDU → Nm_NetworkStartIndication

第 4 步:理解定时器

重点搞清:

  • TimeoutTime
  • RepeatMessageTime
  • WaitBusSleepTime
  • MsgCycleTime

第 5 步:再看进阶功能

最后看:

  • Bus Load Reduction
  • Remote Sleep Indication
  • User Data
  • Passive Mode
  • Communication Control
  • Partial Networking
  • Coordinator Sync
  • Car Wakeup

三十二、CanNm 学习版口诀

你可以直接背这个:

text复制代码

谁发NM,谁就说“我还醒着”
我不发了,不代表立刻睡
只要别人还发,我就继续等
大家都不发了,超时后才去睡
刚醒来先进入Repeat,多发几条告诉大家
真正干硬件切换的是CanSM,不是CanNm

三十三、自测题(含答案)

下面这部分你可以直接拿来复习。
我给你整理成 30 问 30 答


1. CanNm 的核心作用是什么?

答:
CanNm 的核心作用是协调 CAN 网络中各节点从正常工作到总线休眠(Bus-Sleep)的切换,以及从休眠重新唤醒网络。它通过发送和接收 NM 报文来让所有节点达成一致。


2. CanNm 是发业务报文的吗?

答:
不是。CanNm 主要发的是 网络管理报文(NM PDU),不是业务数据报文。


3. CanNm 和 CanSM 最大区别是什么?

答:
CanNm 负责“网络管理协议层面的醒/睡协调”;CanSM 负责“实际 CAN 网络状态和硬件模式切换”。


4. CanNm 对外可见的 3 个操作模式是什么?

答:

  • Network Mode
  • Prepare Bus-Sleep Mode
  • Bus-Sleep Mode

5. Network Mode 里有哪 3 个内部状态?

答:

  • Repeat Message State
  • Normal Operation State
  • Ready Sleep State

6. CanNm 初始化后默认在哪个模式?

答:
默认在 Bus-Sleep Mode


7. CanNm 初始化后默认网络状态是什么?

答:
默认是 released


8. 哪个 API 用于请求网络?

答:
CanNm_NetworkRequest()


9. 哪个 API 用于释放网络?

答:
CanNm_NetworkRelease()


10. requested 和 released 是主状态机模式吗?

答:
不是,它们是和主状态机并行存在的“网络状态”,表示本 ECU 自己是否还需要该网络。


11. Repeat Message State 的作用是什么?

答:
它用于在节点刚进入 Network Mode 时重复发送 NM 报文,让其它节点明确看到该节点已启动并需要网络,同时保证启动稳定性,也可支持节点检测。


12. Repeat Message State 结束后去哪里?

答:

  • 如果网络仍是 requested → 进入 Normal Operation State
  • 如果网络已是 released → 进入 Ready Sleep State

13. Ready Sleep State 的含义是什么?

答:
表示本节点自己已经不再请求网络,停止发送 NM 报文,但仍会等待和监听其它节点,只要还有别人发 NM 报文,它就不会立即进入睡眠。


14. Ready Sleep State 超时后进入什么模式?

答:
进入 Prepare Bus-Sleep Mode


15. Prepare Bus-Sleep Mode 的作用是什么?

答:
给总线和节点一个“收尾时间”,让发送队列清空、总线平静下来,再真正进入 Bus-Sleep Mode。


16. Bus-Sleep Mode 的作用是什么?

答:
降低功耗,使通信控制器进入休眠,并激活必要的唤醒机制。


17. 在 Bus-Sleep Mode 收到 NM 报文时,CanNm 会自动回 Network Mode 吗?

答:
不会自动直接回去。CanNm 会先调用 Nm_NetworkStartIndication() 通知上层,由上层决定后续唤醒动作。


18. 进入 Network Mode 时默认先进入哪个内部状态?

答:
默认先进入 Repeat Message State


19. 什么情况下会通过 CanNm_PassiveStartUp() 进入 Network Mode?

答:
当节点在 Bus-Sleep 或 Prepare Bus-Sleep 下需要被动启动网络管理流程时,可以调用该接口,进入 Network Mode 的 Repeat Message State。


20. NM-Timeout Timer 是干嘛的?

答:
用于检测在一定时间内是否还存在 NM 报文发送/接收活动,从而判断网络是否仍应保持唤醒。


21. 哪些事件会重启 NM-Timeout Timer?

答:

  • 在 Network Mode 下成功接收 NM 报文
  • 在 Network Mode 下成功发送 NM 报文确认

22. RepeatMessageTime 是什么?

答:
它决定 CanNm 在 Repeat Message State 要停留多久。


23. WaitBusSleepTime 是什么?

答:
它决定 CanNm 在 Prepare Bus-Sleep Mode 里等待多久后进入 Bus-Sleep Mode。


24. MsgCycleTime 是什么?

答:
它是 NM 报文的周期发送时间。


25. CanNm 为什么支持 Bus Load Reduction?

答:
为了减少总线负载,避免所有节点都按相同频率持续发送 NM 报文。启用后通常只有少数节点交替发报文即可维持网络唤醒。


26. Passive Mode 是什么?

答:
Passive Mode 下节点只接收 NM 报文,不发送 NM 报文。


27. Communication Control 控制的是什么?

答:
控制的是 NM 报文发送能力,不是整个 CanNm 模块完全停掉。


28. User Data 是什么?

答:
NM 报文中可选的一块用户数据区域,可通过 CanNm_SetUserData()/CanNm_GetUserData() 或 COM/PduR 路径访问。


29. PNI bit 是什么?

答:
PNI(Partial Network Information)bit 表示该 NM 报文携带了 Partial Networking 相关信息。


30. CanNm 的一个经典运行时错误是什么?

答:
CANNM_E_NETWORK_TIMEOUT,表示 NM-Timeout Timer 在某些不该异常超时的状态下超时了。


三十四、再送你 10 个进阶题(方便你以后面试)


31. CanNm 的算法是集中式还是去中心化?

答:
去中心化(decentralized direct network management strategy)。


32. 哪个接口读取当前 CanNm 状态和模式?

答:
CanNm_GetState()


33. 哪个回调表示收到 NM 报文?

答:
CanNm_RxIndication()


34. 哪个回调表示 NM 报文发送成功/失败确认?

答:
CanNm_TxConfirmation()


35. Repeat Message Request Bit 的作用是什么?

答:
用于请求节点进入或重进 Repeat Message State。


36. ActiveWakeupBit 什么时候置 1?

答:
当 CanNm 因调用 CanNm_NetworkRequest() 从 Bus-Sleep 或 Prepare Bus-Sleep 进入 Network Mode,且启用了 Active Wakeup Bit 支持时。


37. ActiveWakeupBit 什么时候清 0?

答:
离开 Network Mode 时清零。


38. Remote Sleep Indication 是什么意思?

答:
表示当前节点判断“其它所有节点都准备睡了”。


39. CanNm 和 CanSM 在什么场景下会联动?

答:
当 PN 相关场景下 NM 报文发送确认超时,CanNm 可能调用 CanSM_TxTimeoutException() 让 CanSM 去做进一步网络恢复。


40. CanNm 为什么要有 Repeat Message State,而不是直接 Normal Operation?

答:
为了让刚启动的节点更明显地通知整个网络、提升启动稳定性,并支持节点检测等功能。

Logo

CANN开发者社区旨在汇聚广大开发者,围绕CANN架构重构、算子开发、部署应用优化等核心方向,展开深度交流与思想碰撞,携手共同促进CANN开放生态突破!

更多推荐