文章目录
- 前言
- Autosar CanNm标准中的相关参数
- CanNmAllNmMessagesKeepAwake
- PN过滤功能
- CanNm_ConfirmPnAvailability
- 问题描述
- 问题原因排查
- 解决方案
- 扩展
- 总结
前言
Autosar Nm中针对于支持PN功能的收发器,要求PNC停发后允许进入休眠模式,开发过程中遇到PNC停发后无法休眠,本文对该问题进行排查与处理。
Autosar CanNm标准中的相关参数
此处我们讨论支持PN功能的情况,也就是CanNmPnEnabled为True
CanNmAllNmMessagesKeepAwake
当该参数配置为Trrue时,只要收到Nm报文,就会认为是有网络唤醒请求
当该参数配置为false时,需要Nm Pdu中PNI位为1且有对应的PNC请求才会认为是有效的网络唤醒请求
对于不支持PN功能的can收发器,该配置项可以配置为True以防止PNI置位时被频繁唤醒
对于支持PN功能的can收发器,该配置项需要配置为false,保证PNI置位但没有PNC请求时也可以进入休眠模式。
注意:此时can收发器端配置data有效数据时不能包含PNI位,只需关联对应的PNC位为1即可。
标准解读:
1.对于支持PN功能的ECU,当PNI为0时,CanNmAllNmMessagesKeepAwake为TRUE时,仍需要认为接收到有效的Nm Pdu,也就是能够维持唤醒。
2.对于支持PN功能的ECU,当PNI为0时,CanNmAllNmMessagesKeepAwake为FALSE时,需要忽略接收到的Nm Pdu,也就是会走网络管理下电流程(Ready Sleep-PreBus Sleep-Bus Sleep)
3.对于支持PN功能的ECU,当PNI为1且没有关联的PNC置位时,CanNmAllNmMessagesKeepAwake为FALSE时,需要忽略接收到的Nm,Pdu,也就是会走网络管理下电流程
4.对于支持PN功能的ECU,当PNI为1且没有关联的PNC置位时,CanNmAllNmMessagesKeepAwake为TRUE时,仍需要认为接收到有效的Nm Pdu,也就是能够维持唤醒
PN过滤功能
此处有三个配置参数,CanNmPnInfoOffset,CanNmPnInfoLength,CanNmPnFilterMaskByteValue,Offset表示PNC从Nm Pdu中的第几个字节开始算,Length即为PNC的字节数,MaskByteValue配置有效的PNC位
标准中示例如下:
例子中两个字节的PNC,第一个字节没有有效的PNC位,第二个字节中有有效的PNC
CanNm_ConfirmPnAvailability
为了通知CanNm能够支持PN过滤,需要CanSm调用CanNm_ConfirmPnAvailability函数
问题描述
Nm PDU中关联的PNC停止发送,ECU报文停发,但未进入休眠模式,导致耗电严重
问题原因排查
停发PNC后,Nm状态仍处于Ready Sleep状态,Nm Pdu仍能正常接收,查看CanNm配置项CanNmAllNmMessagesKeepAwake已经为FALSE。在CanNm_RxIndication中默认PDU是收到的,只有CanNmAllNmMessagesKeepAwake为FALSE且CANNM_GetPnMsgFilteringStatus为TRUE才能允许PDU未接收
而CANNM_GetPnMsgFilteringStatus一直为FALSE,所以Nm PDU一直能收到
排查发现CANNM_SetPnMsgFilteringStatus没有运行,该函数在CanNm_ConfirmPnAvailability中调用,而CanNm_ConfirmPnAvailability在CanSM_ConfirmPnAvailability中调用,实际CanSm_ConfirmPnAvailability函数没有地方调用了
所以导致Nm Pdu一直是收到的状态,导致无法进入下电过程
解决方案
本质上就是要调用CANNM_SetPnMsgFilteringStatus,可以在初始化完后通过CanNm_ConfirmPnAvailability函数进行调用
注意:该函数传递的参数为nmChannelHandle,需要确认对应的Nm通道是否正确
另外,如果关联的PNC停发后仍然没有进入休眠状态,那么就需要再排查下 PN过滤的参数了。
扩展
标准文档中的推荐流程为:CanTrvc->CanIf->CanSm->CanNm
查看Autosar CanSm文档,CanSm_ConfirmPnAvailability函数由CanIf模块调用
CanIf有对应配置CanIfDispatchUserConfirmPnAvailabilityUL及CanIfDispatchUserConfirmPnAvailabilityName,需要在CanIf中配置为CanSm盒CanSm_ConfirmPnAvailability,且配置CANIF_PUBLIC_PN_SUPPORT为TRUE
这样配置之后,CanIf中的CanIf_ConfirmPnAvailability函数就会调用CanSm_ConfirmPnAvailability了
而CanIf_ConfirmPnAvailability需要由CanTrcv调用,标准中描述如下:
总结
由于我们没有使用CanTrcv模块,所以用标准流程会导致很多check不过,但是知道原理之后,怎么解决问题就很简单了~