目录
前言:AUTOSAR CanSM 简介
CanSM 是 AUTOSAR 架构BSW 中的一个标准模块,主要完成CAN网络状态管理;提供的功能主要包括:
- 通讯模式切换
COMM_NO_COMMUNICATION
COMM_SILENT_COMMUNICATION
COMM_FULL_COMMUNICATION
- BUSOFF 恢复管理
- 波特率切换
- 唤醒确认管理
CanSM接收其他模块(如ComM,Dcm 等)的通讯模式切换请求,按照CAN网络状态管理的逻辑,通过调用CanIf 下层接口,实现对CAN controller 或CAN transceiver 工作状态的切换;或者反过来向其他模块反馈CAN 网络状态;
我们从 AUTOSAR CanSM(1) -- CAN 网络初始化及启动流程-CSDN博客 已经了解到CAN 网络的初始化和启动流程;
在网络没有故障的情况下,CanSM 启动后会保持在FULLCOM 状态的 NO_BUS_OFF 子状态,PduMode 保持在CANIF_ONLINE,通讯模式保持在COMM_FULL_COMMUNICATION,进行网络报文收发的处理;
如果在之后的通讯过程中,网络存在故障(比如CANH / CANL 短接),导致节点进入BUSOFF,一段时间后,故障又消失了,恢复到正常状态,总线出现128次连续11个bit 的隐性电平(允许恢复到正常状态) ,这个时候CanSM 就会执行BUSOFF 恢复流程,尝试将CAN 网络恢复到正常状态;
1. BUSOFF 恢复的前置条件
节点从BUSOFF 恢复到正常状态ERROR ACTIVE 的前置条件是:总线上的故障确实消失了,并且出现了 128次 连续 11个 bit 的隐性电平,这个时候才允许执行节点状态恢复的动作;
CAN Specification 2.0 PART B (3) -- CAN message 传输错误处理、CAN节点故障状态说明-CSDN博客
1.1 CAN 控制器 BUSOFF 的响应动作及恢复措施
以Bosch M_CAN 为例说明 CAN controller 对BUSOFF 的响应动作及恢复措施;
1.1.1 CAN 控制器 BUSOFF 响应动作
MCAN 通过PSR.BO 和CCCR.INIT 两个标志位/ 控制位来指示BUSOFF事件;
BUSOFF 发生后 PSR 寄存器BUSOFF 标志位 PSR.BO 会置位,该标志位由硬件控制,用户只读,BUSOFF 恢复后 PSR.BO RESET为0;
BUSOFF 发生后 CAN controller 控制寄存器 CCCR.INIT 位会被硬件置位,停止CAN controller一些动作使节点不再参与总线活动;
1.2 CAN 控制器 BUSOFF 恢复措施
CAN controller 进入BUSOFF 后, 可以通过用户代码 RESET CCCR.INIT 控制位来将CAN 控制器恢复;
RESET CCCR.INIT 后,CAN controller 会等待总线上出现 129次 连续11个bit 的隐性位后,再将恢复到normal 状态;在切换到 normal 状态时Error Counter 也会RESET 到 0;
MCAN 提供了一些硬件机制,用户可以用来监控 BUSOFF 恢复流程:如RESET CCCR.INIT 后,总线上每出现一次连续11个bit 的隐性电平,接收错误计数器 ECR.REC 会对其进行计数,另外,PSR.LEC 也会被写入一次 Bit0Error 对应的Error Code;
用户可以通过调用 MCAL CAN driver Can_SetControllerMode 的接口函数将,控制器重新设置为STARTED 状态,RESET CCCR.INIT,来实现BUSOFF恢复的操作;
CAN controller 层面BUSOFF 处理方式用中断或者polling 都可以,它们处理BUSOFF 时执行的逻辑是相同的,不同的是,中断的方式对BUSOFF 的响应可以更快一些;BUSOOF 能否恢复主要取决于总线的状态,和用户响应BUSOFF的动作快慢关系不大;一般情况多使用polling的方式处理BUSOFF;
2. CanSM BUSOFF 恢复流程
2.1 底层反馈BUSOFF 状态到CanSM
运行过程中由于CAN 网络故障,节点进入BUSOFF 状态,底层CAN driver 中的BUSOFF 处理函数会取消所有处于pending 状态的发送请求,将控制器状态设置为STOP,然后调用 CanIf_ControllerBusOff 将故障状态往上层上报;
CanIf_ControllerBusOff 会将CAN controller Mode 设置为STOPPED,将Pdu模式设置为CANIF_TX_OFFLINE,然后在调用 CanSM_ControllerBusOff 将故障状态报告给CanSM;CanSM_ControllerBusOff 中置位T_BUS_OFF trigger 信号;
CanSM 状态机管理函数 CanSM_MainFunction 根据 T_BUS_OFF 信号将CAN网络状态设置为COMM_SLIENT_COMMUNICATION,同时通知ComM 和BswM 模块节点的BUSOFF状态,并报出BUSOFF Dem故障,然后将状态机设置到RESTART_CC 子状态,尝试进行BUSOFF 故障恢复;
2.2 CanSM 重启CAN controller
CanSM 状态机在 BUS_OFF_CHECK,NO_BUS_OFF 两个子状态时都可能由于总线故障进入BUSOFF,在收到底层处于BUSOFF 状态的反馈信号后,CanSM 会直接进入RESTART_CC 状态,通过重启CAN controller(由CanIf调用 CAN driver Can_SetControllerMode,将controller模式重新设置为STARTED),来尝试从BUSOFF 恢复;
2.3 快恢复和慢恢复
CAN controller 重启成功后,CanSM 状态机进入TX_OFF 子状态;在TX_OFF 状态,节点不发送数据,并且启动延时计数器,达到设定的延时时间后,节点从TX_OFF状态退出,进入BUS_OFF_CHECK 状态,恢复数据发送;
这个延时时间被定义为BUSOFF 的恢复时间(可以理解为尝试发送数据前的等待时间);并且根据这个时间设置的长短,分为快恢复和慢恢复;执行恢复的次数,用户可以自己定义;比如设置按100ms 的周期执行50 次快恢复后,都按500ms 的周期执行慢恢复;
2.4 BUSOFF恢复状态确认
TX_OFF 状态下,恢复时间到达后,CanSM 状态机进入BUS_OFF_CHECK 子状态;
进入BUS_OFF_CHECK 时,首先根据ECU passive 为 FALSE 或TRUE 将PduMode 设置为CANIF_ONLINE 或 CANIF_TX_OFFLINE_ACTIVE;
然后通过BswM_CanSM_CurrentState API 通知CanSM 的当前状态为CANSM_BSWM_FULL_COMMUNICATION;
再然后通过ComM_BusSM_ModeIndication API 通知CanSM 的当前状态为COMM_FULL_COMMUNICATION;
之后正常的发送数据;并且检查在一段特定的时间内(时间长短用户可设置),节点是否不会再进入BUSOFF 状态;如果再这段时间内又发生了BUSOFF,则重复执行BUSOFF 恢复流程;如果没有再发生BUSOFF,则CanSM 进入NO_BUS_OFF 子状态,正常的收发数据;
2.5 总结
CanSM 处理BUSOFF 的整体流程
推荐:
使用polling的方式处理BUSOFF,并且在时序上保证CAN driver 层BUSOFF 处理函数在CanSM 状态管理函数(CanSM_MainFunction) 之前执行;