• 563查看
  • 0回复

[网络开发] CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16

[复制链接]


该用户从未签到

发表于 7-1-2024 17:04:04 | 显示全部楼层 |阅读模式

汽车零部件采购、销售通信录       填写你的培训需求,我们帮你找      招募汽车专业培训老师


一个控制器进入AutoSAR NM的前提是需要有唤醒源。对于主动唤醒节点,由本地唤醒源,如何确保本地唤醒源唤醒信号的有效性?一般需要经过Check、Set和Valid三步操作,接下来就从软件实现角度聊聊这三步操作。
1如何Check唤醒事件
对于CAN通讯 ,CC(communication controller)或Trcv(Transceiver)可以使用中断或轮询来检测唤醒事件。而CC和Trcv的关系自不必细说,谁离了谁也干不成事(报文无法收/发),如下图:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w1.jpg

当有Can Bus的唤醒事件时,EcuM分不清楚Can Bus唤醒是CC发现的还是Trcv发现的,如果EcuM想知道谁发现的,就需要问问CC和Trcv,你俩谁发现的?EcuM通过调用EcuM_CheckWakeup()来查是CC还是Trcv,这个过程中EcuM其实只会传“圣旨”,即调用EcuM_CheckWakeup(),而实际调查是依靠地方官员(CanIf、CC 或 Trcv)。
1、中断方式Check唤醒事件

当外部中断唤醒事件到来时,可以是Can Controller中断,也可以是CAN Transceiver中断。如下展示了EcuM"圣旨"的传递过程(Check),即中断例程主动调用EcuM的EcuM_CheckWakeup(),让EcuM检查,此方式不拖泥带水,响应迅速。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w2.jpg

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w3.jpg

2、轮询方式Check唤醒事件

相比于中断方式,Polling方式就“磨叽”了,CC和Trcv都不主动告诉EcuM,等EcuM检查,就像小学生考试成绩,考不好不会主动告诉家长,都是家长想起来,主动问自己家熊孩子考的咋样一样的道理。EcuM在自己的Task(比如:10ms)中一个一个检查CC和Trcv,如下所示:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w4.jpg

不管轮询还是中断方式,唤醒事件都是“谁发现谁举报”的原则,即谁发现了唤醒事件,谁有责任告诉EcuM(即调用EcuM_CheckWakeup()),这就是Set部分。

提示:Check时,会对应一个CheckWakeupTimer,这个参数可配。
2硬件可以Check
实际,EcuM并不关心到底谁发现的,它只关心是哪个网络需要唤醒,并将其传递给ComM。那我们思考一个问题:“如果Trcv可以Filter,确保了特定帧唤醒,EcuM是不是可以不用Check?”答:个人赞同。比如目前使用率比较高的NXP TJA1145,这款Transceiver具有PN过滤功能,如果我们的项目中,要求指定Range内的网络管理报文唤醒网络,NXP TJA1145即可将此Range范围的网络管理报文识别出,而不必让Ecu起来(被供电),进行软件过滤,即可直接调用EcuM的EcuM_SetWakeupEvent (EcuM_WakeupSourceType)接口,告诉EcuM有唤醒事件。

接着探究一帧有效的网络管理报文是如何把网络唤醒。

3Set唤醒源
为便于细节的展开,我们将Validate分为3个Part: Part1、Part2、Part3,

由上可知,唤醒事件即可以使用Trcv检查,也可以使用Controller检查,检查方式有中断、轮询两种方式。

假设采用Trcv中断方式检查唤醒事件,当Trcv接收到一帧报文时,与Controller相连的Rx Pin拉低,触发ICU中断(设置下降沿或者双边沿触发),之后进入ICU中断处理程序。

提示:如果Trcv没有设置过滤功能,任何一帧报文均可以使能Trcv控制的SBC,进而唤醒ECU,甚至符合Wakeup-Pattern的总线扰动也能唤醒ECU。如果Trcv(硬件)设置了过滤功能,则可以实现特定的网络管理报文唤醒网络。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w5.jpg

通过上图,我们可以看出:Trcv通过调用EcuM_SetWakeupEvent接口告知EcuM,是谁唤醒ECU,唤醒源在开发阶段事先配置,为每一个唤醒源分配一个句柄(identifier)。Set的主要目的是把唤醒事件挂起,以便EcuM(EcuM_MainFunction())后续检查唤醒事件的有效性,唤醒事件的检查中,可以不Check,但是不能不验证唤醒事件的有效性(Validation)。唤醒事件的挂起操作如下:/* #34 Add this source to the global pending wakeups variable. */EcuM_PendingWakeups |= WakeupSource;将唤醒事件在一个全局变量中置位(一个唤醒源对应一个Bit)。
4EcuM如何Validate唤醒事件
为便于细节的展开,我们将Validate分为3个Part: Part1、Part2、Part3,如下所示:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w6.jpg

Part1

在Set部分,已经通过一个全局变量EcuM_PendingWakeups将待验证的唤醒事件缓存,在EcuM_MainFunction()中即可对待验证的唤醒事件进行验证。在验证唤醒事件之前,需要将Trcv和Controller切换到工作模式,而两者状态的切换,通过EcuM_StartWakeupSources()即可完成,EcuM_StartWakeupSources()进一步调用CanSM_StartWakeupSource()接口。验证过程不能遥遥无期,因此会设置一个验证超时时间参数EcuMValidationTimeout,比如:3s等。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w7.jpg

Part2

至此,真正对唤醒事件的验证才开始,和Check一样,谁发现谁验证。还是老规矩EcuM_CheckValidation()->CanIf_CheckValidation()->EcuM_ValidateWakeupEvent()。这里将WakeupSource = CanIf,不同软件供应商,此处实现方式可能有所不同。注意:一般CanIf_CheckValidation()通过回调函数调用EcuM_ValidateWakeupEvent()。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w8.jpg

如果唤醒事件有效,EcuM有两个工作要做:
    通过ComM_EcuM_WakeUpIndication()告知ComM唤醒事件有效
    通过BswM_EcuM_CurrentWakeup()告知BswM唤醒事件有效
EcuM具体如何告知ComM和BswM呢?如果BswM还没有初始化,EcuM将此信息通过一个全局变量缓存,eg:EcuM_BswM_BufferedWakeups。如果EcuM运行状态>ECUM_STATE_STARTUP_TWO,则调用BswM_EcuM_CurrentWakeUp()接口。而对于ComM,如果ComM初始化完成,则调用ComM_EcuM_WakeUpIndication()接口;如果ComM未初始化完成,也会通过一个全局变化缓存此信息,eg:EcuM_ComM_BufferedWakeups。Part3

此部分和Part2是一个if..else..关系,此部分表示唤醒事件无效后的处理动作,如果唤醒事件无效,EcuM会将此信息告知BswM,让BswM执行对应的ActionList。

同时,EcuM调用接口EcuM_StopWakeupSources()去切换Trcv和Controller的状态,即关闭两者,之后对应的报文无法接收。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w9.jpg

5ComM状态切换
在Part2中,唤醒事件有效以后,会调用ComM_EcuM_WakeUpIndication()接口,之后ComM状态如何切换呢?

ComM对应的通道会切换到COMM_NO_COM_REQUEST_PENDING子状态,如下所示:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w10.jpg

如上可以看出:ComM对应的通道会切换到COMM_NO_COM_REQUEST_PENDING子状态,存在多个or情况,收到网络管理报文也属于其中一种。

当没有User主动请求通信时,唤醒过程被认为是Passive Wakeup过程,比如:收到网络管理报文就属于Passive Wakeup过程,如果CanNM模块在Bus-Sleep Mode收到网络管理报文,会调用Nm_NetworkStartIndication()通知NM模块,之后NM模块通过ComM_Nm_NetworkStartIndication()接口告知ComM。被动唤醒时,EcuM、ComM和NM的交互时序如下所示:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w11.jpg

注意:

ComM从COMM_NO_COM_REQUEST_PENDING子状态想要进入COMM_FULL_COM_NETWORK_REQUESTED,需要满足两个条件:

    通信允许,即CommunicationAllowed = True

    CanSM请求COMM_FULL_COMMUNICATION


CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w12.jpg

谁控制CommunicationAllowed = True

既然需要满足CommunicationAllowed = True,那谁来控制这个条件呢?对于Flexible EcuM,每个Channel的CommunicationAllowed条件由BswM调用ComM_CommunicationAllowed()接口控制。
CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w13.jpg

我们知道,BswM干活有规矩:先模式仲裁(Arbitration),后执行对应的动作(ActionList),两者配合如下所示:

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w14.jpg

模式仲裁请求包括:Requests和Indications,而BswM_EcuM_CurrentWakeup()接口的调用,属于Indication,意味着EcuM告知BswM,有效的唤醒事件已确认。同时,检查是否收到网络管理报文(如果Trcv具有Filter功能,即识别网络管理报文,则唤醒事件有效 等价于收到网络管理报文,软件即可不用处理),如果这两个Rule满足,则允许通信,之后BswM执行对应的ActionList,其中就包括ComM_CommunicationAllowed()接口的调用,即设置CommunicationAllowed = True。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w15.jpg

谁请求COMM_FULL_COMMUNICATION

当ComM对应的Channel允许通信以后,且EcuM在RUN Phase时,进入

COMM_FULL_COMMUNICATION状态,谁请求COMM_FULL_COMMUNICATION呢?如果回答了这个问题,就意味着接下来通信COM、网络NM对应的报文可以外发,即:对应节点的网络被一帧网络管理报文唤醒了。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w16.jpg

在EcuM调用ComM_EcuM_WakeUpIndication()接口时,EcuM即请求了
COMM_FULL_COMMUNICATION::COMM_FULL_COM_READY_SLEEP状态,因此ComM可以在其Task(ComM_MainFunction)中进行状态的切换,此时ComM会干两件事:
    打开通信栈,即请求对应的XxSM模块进入FULL_COMMUNICATION状态,Eg:CanSM_StartWakeupSource()。代码示例:
ComM_RequestBusSMMode( Channel, COMM_FULL_COMMUNICATION );

    切换网络状态,即调用接口Nm_PassiveStartUp(Channel),网络进入NetworkMode::RepeatMessageState。
Nm_PassiveStartUp()进一步的调用CanNm_PassiveStartUp(),之后的网络流程如下所示:
CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w17.jpg

至此,本文将收到一帧网络管理报文,到网络唤醒的流程“串烧”了一遍,当然,这里只是讨论了一种实现方式,实际的工程中,可能存在些许偏差。

CAN通讯系列补充篇:本地唤醒源是如何唤醒控制器的?16w18.jpg

参考资料

AUTOSAR_SWS_COMManager.pdf

AUTOSAR_SWS_ECUStateManager.pdf

AUTOSAR_SWS_BSWModeManager.pdf

AUTOSAR_SWS_CANNetworkManagement.pdf

快速发帖

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|Archiver|汽车工程师之家 ( 渝ICP备18012993号-1 )

GMT+8, 1-2-2025 14:41 , Processed in 0.362505 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2013 Comsenz Inc.