这一章来看看位于Communication Stack的CanNm模块(CAN Network Management)。
首先来简单说说NM(网络管理)的概念,现在汽车上ECU非常之多令人乍舌,设备越多,这电就要越扣扣嗖嗖的用,那该怎么省电呢?有一种方法就是在某些用车场景用不到的ECU,那么就让你进入休眠不工作,当需要这个ECU时,再去把你唤醒,而NM就是为了去实现这个省电小技巧基于总线报文而创造出来的一个玩意。
在介绍CanNm模块之前,首先需要搞清楚CanNm模块和NM模块的关系。
如下图所示,Nm 模块位于 AUTOSAR 的通信服务层,对上与ComM 交互,对下控制各总线网络管理模块,为 ComM 提供统一的网络管理功能,同时当开启网络协同功能时,协调各总线网络管理模块之间的状态关系。
CanNm模块其实只是CAN总线上的NM,而LIN, FlexRay也有其对应的NM,大家都大同小异,都实现着一模一样的目的,所以对于CanNm模块和NM模块的关系,说得再简单点,NM模块是一个经理,CanNm模块是真正打工人,那么站在NM之上的ComM模块则是老板了,ComM模块后面会介绍到,这里不多说。
这里推荐一篇文章,里面详细的讲述了NM模块的一些基本理论知识:《一文搞懂AUTOSAR CanNm模块》,满满的干货。
CanNm 模块主要功能如下:
1. 初始化
2. 网络管理报文发送
3. 网络管理报文接收处理
4. 同步睡眠和唤醒功能
5. 向应用层提供网络上节点信息
6. 降低总线负载机制
如果CanNm模块初始化成功,即:调用函数CanNm_Init成功,则CanNm模块应将网络管理状态设置为总线睡眠模式(Bus-Sleep Mode)。 CanNm模块应该在CanIf初始化之后,并且在任何其他网络管理服务被调用之前,进行初始化。CanNm_Init函数应通过传递的配置指针参数选择活动配置集。如果CanNmGlobalPnSupport设置为TRUE,并且CanNm已被初始化(调用CanNm_Init),则CanNm需停止NM消息传输超时计时器(NM Message Tx Timeout Timer)。在初始化期间,CanNm模块应停用总线,减少总线负载。初始化后,CanNm模块应通过停止消息周期定时器(Message Cycle Timer)来停止网络管理PDU的传输。
CanNm 模块的状态切换是被动的,根据自身控制器和网络的当前状态来调用相关接口发起 CanNm 模块状态切换,模块状态切换后会调用上层 NM 模块提供的回调接口以通知应用层。NM模式切换图如下所示:
具体的模式切换条件可以参考文章:《一文搞懂AUTOSAR CanNm模块》里面的描述。
前面一节介绍了一下NM里面的状态机切换,可以说是花里胡哨,及其复杂,非常难理解,但是其实提现到CAN总线上的表现却变得异常的简单,当设备处于正常工作时,NM模块就会让ECU周期性的在总线上发送NM报文告知其他ECU自己的状态,当它需要休眠时或者它想要休眠时,哎,它就会停止发送NM报文,有些做小弟的ECU,当它收不到老大的报文超时了,它就知道了自己也要休眠了。
NM报文的结构如下图所示:
Source Node Identifier代表这个节点的唯一标识号,它的位置应可通过CanNmPduNidPosition配置为字节0,字节1或者关闭(off),关闭后则可以用作User Data。
Control Bit Vector为控制位向量,简称CBV,里面包含了网络管理中非常重要的信息,其位置也可以通过CanNmPduCbvPosition配置为字节0,字节1或者关闭(off),关闭后则可以用作User Data。
下图显示了CBV里面每一位所包含的信息:
远程睡眠指示功能是指当本地节点一直工作在 Normal Operation State,在一定时间内却一直收不到总线上其他节点的网络管理报文,此时本地节点 CanNm 认为总线上除了自己,其他节点都已经满足睡眠,进而向上层 NM 模块报告远程睡眠指示并在 CanNm 模块内部记录此事件,后续上层 NM 模块还可以调用 CanNm_CheckRemoteSleepIndication()函数接口主动查询远程睡眠是否已经发生。该功能一般在网关节点上使用。
AUTOSAR CanNm 算法基于周期传输的网络管理 PDU 实现,接收到 NM PDU 表示发送此 NM PDU 的节点需要网络保持唤醒。如果某节点准备进入 Bus-Sleep Mode,此节点就停止发送 NM PDU,但是只要能收到网络上其他节点发送的网络管理报文,此节点就推迟进入 Bus-Sleep Mode。最终,不再收到其他节点的 NM PDU,并且此状态持续指定的时间后,所有的节点均同时开始进入 Bus-Sleep Mode。
NM PDU 的发送周期取决于时间参数 CANNM_MSG_CYCLE_TIME,同一网络中所有节点的此时间参数都相同。当网络中节点数量比较多,并且不采取任何措施时,就容易导致总线负载过高。为解决此问题,提出了降低总线负载机制。实现降低总线负载机制需遵循如下两点:
(1)如果节点成功接收 NM 报文,则此节点发送周期定时器重置为节点特殊参数CANNM_MSG_REDUCED_TIME,此参数取值范围为 1/2(CANNM_MSG_CYCLE_TIME) ~ CANNM_MSG_CYCLE_TIME。
( 2 ) 如 果 节 点 成 功 发 送 NM 报 文 , 则 此 节 点 发 送 周 期 定 时 器 重 置 为CANNM_MSG_CYCLE_TIME。
遵循此两点则产生如下结果:网络中仅拥有最小的 CANNM_MSG_REDUCED_TIME 的两个节点(假定为 1、2 节点)交替发送 NM PDU,如果其中一个节点(节点 1)准备进入休眠而停止发送 NM PDU,则其余需要总线唤醒的节点中 CANNM_MSG_REDUCED_TIME 值最小的节点,比如 3节点,则代替刚停止发送 NM PDU 的节点,开始与 2 节点交替发送 NM PDU。依次类推,直到网络中只有一个节点需要总线唤醒时,则按照CANNM_MSG_CYCLE_TIME 周期发送NM PDU。
这样做的目的,就是让NM报文由一开始的所有ECU报文周期性发送变成了总线上同一段实际只有两个ECU交替发送NM报文,前提时是这些ECU开启了这个机制。
CanNm 模块中有对本模块通信控制的功能,可根据实际情况,在不需要网络管理模块 通 信 时 ( 如 诊 断 中 0x28 诊 断 服 务 ) , 上 层 接 口 可 调 用 通 信 控 制 接 口 函 数CanNm_DisableCommunication()和CanNm_EnableCommunication()来控制网络管理模块通信。
CanNm 模块使用的定时参数如下表所示:
参数名称 | 描述 |
---|---|
CanNmImmediateNmCycleTime | 定义快速发送 NM PDU 的发送周期 |
CanNmMsgCycleTime | 定义 NM PDU 的发送周期 |
CanNmMsgReducedTime | 定义在降低总线负载下的 NM PDU 发送周期 |
CanNmMsgTimeoutTime | 定义 NM PDU 发送超时时间 |
CanNmRepeatMessageTime | 定义 RepeatMessage 状态下的持续时间 |
CanNmTimeoutTime | 定义等待 NM PDU 的超时时间 |
CanNmWaitBusSleepTime | 定义总线休眠的超时时间 |
补充:除了以上简单介绍的几大点,CanNm模块还有一大堆的细节,大家如果想更深入了解CanNm模块,可参加文章《AUTOSAR CAN NM(CAN网络管理)》。另外还可参考AUTOSAR官方文档《AUTOSAR_SWS_CANNetworkManagement.pdf》。再推荐一篇干货满满的文章:《AUTOSAR架构下关于CanNm的几点思考》。