这一章来看看Communication Stack的CanSM模块(CAN State Management)。SM模块跟NM模块类似,每一种总线都有自己的SM模块。这里还是以CAN总线为例。
首先来看看CanSM模块在AUTOSAR架构中的位置:
可以看到CanSM和上一章介绍的CanNm是两兄弟,都是基于interface层,对上则服务于ComM服务。只不过两兄弟所实现的功能不一样,在具体介绍CanSM模块之前,得先搞清楚状态管理是个什么玩意。首先这里管理的状态其实是对应其总线的通信状态,所以CanSM模块管理的就是CAN总线的通信状态,而这里的通信状态则包含能不能发送报文,能不能接收报文,总线上有没有错误等。
CanSM模块针对CAN总线状态而言,由上而下,CanSM接收其他模块的总线状态切换请求并通知CanIf模块去执行,由下而上,CanSM接收CanIf模块的总线状态切换反馈并汇报给其他模块。
下图显示了在AUTOSAR的BSW层中其他模块与CanSM的交互情况:
ECuM模块会初始化CanSM模块,并与CanSM模块交互进行CAN总线唤醒的验证。ComM模块使用CanSM模块请求CAN网络的通信模式,CanSM模块会将其CAN网络的当前通信模式通知给ComM模块。CanSM模块使用Canlf模块来控制CAN控制器和CAN收发器工作模式,Canlf模块通知CanSM模块CAN总线相关事件。CanSM模块向Dem模块报告总线特定的故障信息。CanSM将总线特定的模式更新通知到BswM模块。CanSM模块将部分网络可用性通知给CanNm模块,并在部分联网的情况下处理已通知的CanNm超时异常。CanSM模块向Det模块报告开发和运行时错误。
CanSM提供的主要功能主要有:
1. 总线模式切换
2. Busoff 恢复管理
3. 切换波特率
4. 唤醒确认管理
CanSM模块针对总线模式控制有一个内部状态机,它会接收其他模块的总线模式切换请求以及总线状态变化反馈才进行状态机切换,其内部状态机切换如下图所示:
*注:高清图请参考AUTOSAR官方文档:《AUTOSAR_SWS_CANStateManager.pdf》。
NOT_INITIALIZED 状态下,只能调用 CanSM_Init。
PRENOCOM/WUVALIDATION/PRE_FULLCOM/CHANGE_BAUDRATE/SILENTCOM_BOR 为中间状态,正常情况下,CanSM不会停留在这些状态中,在这些状态下,调用 CanSM_RequestComMode 会被拒绝。
NOCOM\FULLCOM\SILENTCOM 为稳定状态,处于这些状态下,可接受新的CanSM_RequestComMode 请求。
上面提到了CanSM有三种稳定状态,分别为NOCOM \FULLCOM \SILENTCOM,其中NOCOM的就是无通信,不能收发,FULLCOM为全通信,可收可发,从字面意思上就非常好理解,至于SILENTCOM则是只能收不能发,通常用在系统想要sleep的时候。
关于CanSM的状态机切换非常复杂,上述提到了几种大状态下又会有自己的子状态机,但是不管它多复杂对我们使用它却并没有什么关系,这就是AUTOSAR的可怕之处,它会安排好一切,我们只需要按照需求调用接口和使用回调就行了。在这里,对状态机的详细切换机制我就不多作说明了,大家可以参考这两篇文章:《AUTOSAR通信之CAN状态管理:CanSM》,《CAN网络状态机》。
除了上面所说的总线状态机,CanSM模块还有另外一个小型状态机,那就是用来实现的Busoff 恢复机制。
当CanSM模块从CanIf模块收到 Busoff 通知时,将会进入 Busoff 恢复的状态,恢复机制如下:
尝试恢复指的是,重新打开Can的发送能力,并从Busoff Recovery状态切换至CHECK_BUS_OFF状态。在首次进行快恢复和慢恢复时,CanSM模块会分别给出回调函数通知用户。
当 CanSM 尝试恢复 Busoff 后,有两种方法对总线是否恢复进行确认。
Busoff 恢复成功后,BUS_OFF_CHECK状态将切换为 NO_BUS_OFF状态,总线通信恢复正常(注:BUS_OFF_CHECK和NO_BUS_OFF是FULLCOM状态中的两个小状态)。
如果Busoff 恢复不成功,节点一直在慢恢复期,意味着该节点不会外报文(应用报文和网络管理报文均不会外发),其他节点会上报对应的节点丢失故障。
关于BusOff恢复机制的详细过程,我这里也不多说了,感兴趣的朋友可以参考文章:《CanSM模块如何处理Busoff等问题呢》。
CanSM模块提供接口CanSM_ChangeBaudrate可以切换CAN总线通信波特率,但是只有在FULLCOM状态且没有Busoff 时才能调用CanSM_ChangeBaudrate,其他状态调用 CanSM_ChangeBaudrate 会被拒绝。
当系统进入休眠后,CAN 控制器也进入休眠状态。当发生 CAN 通道唤醒事件时,EcuM 会 调 用 CanSM模块的CanSM_StartWakeupSource() 函 数 ,CanSM状态机会由NOCOM状态进入CANSM_BSM_WUVALIDATION状态,将硬件状态设置为正常工作态。此时硬件可以接收到网络上的报文,CanIf 模块会判断该唤醒帧是否合法。若判断结果为合法, ComM 会 调 用 CanSM 模 块 的CanSM_RequestComMode()接口请求 CanSM 进入 FULLCOM 模式, 若结果为非法,则 EcuM 会调用 CanSM 模块的CanSM_StopWakeupSource()函数,由CanSM将硬件重新设置为休眠状态。
补充:除了以上简单介绍的几大点,CanNm模块还有一大堆的细节,大家如果想更深入了解CanNm模块,请参考AUTOSAR官方文档《AUTOSAR_SWS_CANStateManager.pdf》。