编辑推荐: |
本文将主要介绍了AUTOSAR基础篇之FiM模块的基本理解与认识等相关知识。希望对你的学习有帮助。
本文来自于知乎,由火龙果软件Linda编辑,推荐。 |
|
今天天气晴朗,惠风和畅,再加上心情愉悦,着实是个写文章的好日子。之前的文章跟大家分享过DEM模块的整体关系以及针对DTC、Event的细节性的阐述,分享文章只是抛砖引玉,希望能够给大家些许帮助,如需回忆,可以直接点击文尾相关链接进行查看。本文将立足于文章AUTOSAR-DEM模块的几点思考的基础上,来重点分享我对FiM模块的基本理解与认识,该模块是故障监控的最后一环,也就意味着针对故障监控的分享就暂时告一段落了。
前言
你清楚以下几个问题吗?
当系统发生故障时,系统应该怎样做出反应呢?
如何实现当故障发生时,系统做出相应的可预知行为呢?
我们经常讲的系统降级跟FiM到底是什么关系?
FiM与其他基础软件模块是如何交互的呢?
如何实现Event与FiD的Mapping关系?
......
这篇,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:
FiM模块主要功能
通过对AUTOSAR标准文档《AUTOSAR_SWS_FunctionInhibitionManager》的分析,总结如下:
FiM模块提供了一种基于抑制场景的功能降级策略,同时该抑制场景可配置;
可通过特定的Function Identifier来实现相应的抑制场景;
抑制场景可基于Dem模块的Event在FiM模块中根据降级需求完成映射;
FiM模块为BSW以及SW-C各模块的抑制场景提供了一种有效的降级手段;
简而言之,当SW-C或者BSW层发生故障发生时,会将故障即Event上报给到DEM模块,DEM模块会通过某种关系通知到FiM模块,FiM模块通过Function
Identifier再次去告知SW-C以及BSW层做出相应的降级行为。如下图1所示,以SW-C模块上报故障为例,较为清晰了表示了彼此之间的作用关系:
图1 FiM与其他模块的交互关系
其中,红色虚线表示上报故障Event,蓝色虚线表示广播FID状态。
基于上图,我们清楚了抑制场景可以通过Function Identifier(以下简称FID)来表示,某个抑制场景FID跟某个特定故障Event进行Mapping(即一对一关系),也可以是某个FID与多个Event进行Mapping(即一对多关系)。
在此有小伙伴可能会联想起Event与DTC也存在一对一或者一对多的关系。鉴于Dem模块与FiM模块密切相关,我便一并于此梳理下Event
、DTC、FID三者之间的映射关系,防止出现不必要的混淆。
如下图2所示,描述了Event ID、DTC ID、DTC三者之间的映射关系。
图2 Event ID与DTC之间的Mapping关系
注意:在图2中的DTC ID与常说的DTC会有所区别,DTC ID指的是软件内部自动给每个DTC定义的编号(一般从0...n),这部分编号可以通过配置工具生成,而DTC则就是客户要求定义的三个字节的DTC
Number。
由上可知,Event ID与DTC ID既可以是1对1关系,也可以是对对1关系,同时DTC ID与DTC则始终是1对1的关系,最终也就是Event
ID与DTC之间既可以是1对1,也可以是多对1关系。
之所以存在1对多关系,主要是为了便于对Event 进行分类整合,减少DTC的数目,以便于我们对故障快速分析,对于具体是哪个故障,可通过相关诊断服务进行获取,不同供应商可能做法会不一致,如通过1906或者内部诊断服务来进行获取相应的Root
Cause。
如下图3所示,描述了Event ID与FID之间的映射关系。
图3 Event ID与FID 之间的Mapping关系
注意:图中Event ID也是软件内部给每个Event定义的编号(范围从0...n),这部分也是通过工具自动生成。
由此可见,Event ID与FID之间可以实现1对1关系,即某个故障会导致功能层面某个抑制场景;同理,两者也可以是实现多对1关系,即某类events发生时,就都会导致同一功能抑制场景的发生,至于两者如何实现映射关系,后文会进行讲述。
通过上述几个部分的介绍,我们知道FiM的主要功能逻辑就是基于Dem模块上报的Event状态,来触发相应的FID,然后BSW层或者SW-C层相关子模块根据这些FID状态来实现相应的功能抑制场景(俗称:功能降级)。
FiM模块主要功能:获取来自Dem模块的Event Status,置位FiM模块的FID。
FiM模块基本参数
为了更好地跟大家分享下列内容,特意将FiM模块用到的几个较为重要的参数在这里集中讲解一下。
图4 FiM模块主要参数
在图4中,我们看到有Function Inhibition(以下简称FID),Event Monitor
Status来自于Dem模块的输出,Inhibition Mask是FID置位的前提条件,它会与Event
Monitor Status进行与运算。
Function Identifier Counter(以下简称FID Counter),用于描述当前导致FID置位的Event数目,该Counter会随着导致FID置位的Event数目增加而增加,减少而减少。
FiM模块交互关系
那么知道了FiM模块的主要功能,FiM又是如何与其他模块进行交互来完成其上述功能的呢?由于FiM模块做出相应Response的数据来源是Dem模块,我们首先来看看FiM模块与Dem模块之间的交互调用关系。
FiM模块与Dem模块交互关系
FiM模块的输入是来自Dem模块的Event Status,输出就是FID的状态。在此需要特别介绍几个参数取值如下:
Event Status: 即之前文章讲到的一个Byte的Event status,每一个Bit代表相应的含义;
Inhibition Mask:用于决定什么样的Event Status会触发上述FID置位,有以下三种取值:
Inhibit if Failed:当Event Status Bit0 = 1时,该值就为1,否则为0;
Inhibit if Tested: 当Event Status Bit6 =0时,该值为1,否则为0;
Inhibit if Not Tested: 当Event Status Bit6 =1时,该值为1,否则为0;
FID: 全称Function Identifier,取值就是Bool类型 TRUE or FALSE,举例FID_1说明如下:
FID_1 == TRUE: 即抑制场景不激活,功能不降级;
FID_1== FALSE:即抑制场景激活,功能降级;
FID Counter:用于表征当前存在几个Event同时发生导致了该类型的抑制场景激活,进而功能降级;
如下图5所示,表示了来自Dem模块的Event Status,与FiM模块中的Inhibition
Mask、FID、FID Couner这四者之间的计算关系。
图5 FiM模块主要参数的计算关系
由图可知Event ID的状态与Inhibition MASK是位与的关系,如果位与的结果为1,那么相应Mapping
的FID Counter就会加1。其中每个FID只能选择其中一种类型Inhibition MASK,这个是在工具中静态配置,不支持动态更改。
如果多个Event ID发生且与Inhibition MASK位与的结果为1时,那么FID Counter又该如何表现呢,如下图6所示:
图6 FID Counter与Event触发的关系
如上图6所示,假设Event A,EventB、EventC均Map了FID_A,也就意味着当这三个Event中任意一个或多个发生时,FID_A就会置位,即FID_A
== FALSE。另外,每一个FID Counter初始值均为0且值永远大于等于0。
系统降级算法规则:当FID_A Counter >0, FID_A就会置位,即为FALSE,相应的系统降级行为就会发生。
当下列情况时,FID_A Counter 如何变化呢?
通过上述场景分析得知,只要FID_A Counter不等于0,FID_A 就会等于FALSE,系统就会降级。不过在此需要特别提醒的是虽然此时你知道系统降级了,但是从FID你无法知道到底是哪个Event导致的降级,此时就需要通过相关的诊断服务读取内部的Event并且该Event也确实Map了该FID,那么你就可以锁定该Event就是原因所在。
FiM模块与SW-C模块交互关系
如下图7所示,FiM模块的FID 状态最终需要给到各个SW-C层模块使用,SW-C模块通过主动去询问所需要检查的FID状态,来做出相应的系统降级行为。
图7 FiM与SW-C交互关系
图7实际上可以理解为图1的具体实例,在该实例中Sensor SW-C层将Event(anti_pinch)通过下面几个阶段来完成系统降级过程。
S1: Front-Left Window-lifter SW-C 上报故障给到Error Management模块;
S2: Error Management模块会识别出为Event anti_Pinch 故障,并调用Dem模块接口通知该Event
Status发生变化;
S3: Dem模块会调用FiM模块相应的函数接口来通知FiM该Event Status对相应FID的影响;
S4: SW-C模块接收到会轮询相应的FID,然后做出相应的系统降级响应。
此处有小伙伴们可能就问了,既然SW-C层会主动上报故障,那为什么需要兜一圈在进行系统降级呢,时效性怎么保证呢?
其实这里有几个方面的考虑:
AUTOSAR的精髓就在于实现了各模块的解耦并降低各模块的集成难度,而如果自己识别故障自己主动降级的后果就是当同时出现多个不同类型的故障时,系统就没法知道是哪个故障导致的系统降级,不便于排查问题;
通过FiM模块就可以建立起各Event ID与FID的关系,快速能够定位问题;
如果需要考虑到时效性问题,可能需要从FiM模块本身的实现方式去优化或者其他模块协助优化来解决;
FiM模块主要函数调用接口
从上面的讲解中,相信大家对Dem、FiM、SW-C、Error Management 这四个模块之间的作用关系有了较为清晰的了解。接下来我们就来重点看下FiM模块与其他模块之间的主要的函数调用接口是如何使用的,以便让我们日后在调试问题的过程中,遇到系统降级的问题,有一个较为清晰的思路去理解中间的数据流,快速定位问题所在。
FiM_Init:
该函数是为了完成FiM相关结构体的初始化工作。如果DET模块使能,可以判断FiM模块是否初始化成功,或者可以通过一个静态变量是否发生变化来判断有无初始化完成。
因为如果FiM模块没有完成初始化,就被其他模块调用其内部的函数,就会返回E_NOT_OK,所以调用FiM其他函数接口之前必须完成FiM模块的初始化。
FiM_DemTriggerOnMonitorStatus:
该函数是为了提供给Dem模块当Event Status发生变化时通知到FiM模块的接口。一旦Event
Status 发生变化,Dem就会主动调用该函数,通知FiM,这本质上就是一种Trigger Action行为。
其实FiM获取Event Status状态变化,还有一种方法就是polling方式,但是Polling方式有一个缺点,当Event数目比较大时,有时候就无法察觉到某些Event
Status的快速变化,所以一般而言,都优先选择这一种Trigger 方式来完成对FiM模块的Event
Status 通知。
FiM_GetFunctionPermission:
该函数是为了提供给SW-C或者BSW模块来获取FID的状态。如果请求的FID超出范围,那么FID就会直接返回FALSE。如果FiM模块还没有初始化完成,同理,调用该函数也会直接返回FALSE。
FiM_SetFunctionAvailable:
该函数用来给BSW或者SW-C层来设置某功能是否可用,如果输入参数为TRUE,那么该功能可以正常使用;若输入参数为FALSE,则该功能就会被Disable。
FiM_MainFunction:
该函数是为了实现对Event Status与Inhibition MASK的计算,此处有两种方式,一种就是Polling方式,另外一种就是Event
Trigger方式,这两种方式的使能通过工具选项FiMEventUpdateTriggeredByDem
是否为TRUE决定。
FiM模块函数调用关系
基于上述函数的理解,我们来进一步重点看看FiM模块的初始化过程以及FiM跟随Event Status变化的函数调用过程。在理解函数调用关系的基础上,为我们实现代码调试、软件编写将起到相应的辅助作用。
FiM模块初始化过程
如下图8所示,表示了FiM在启动过程中的初始化过程。
图8 FiM模块初始化过程
在FiM模块初始化的过程中,应当按照以下流程完成初始化:
S1:EcuM模块首先调用Dem_Preinit接口;
S2:通过NVM_ReadAll函数来获取最近存储的所有Event的状态;
S3:EcuM模块调用FiM_Init函数来完成内部变量的初始化;调用结束之后,并不能够立即被使用;
S4:EcuM模块调用Dem_Init完成Dem内部变量的初始化,然后在其内部调用FiM_DemInit来最终完成FiM模块的初始化;
S5:从S4开始Dem模块与FiM模块就最终完成了初始化,其相关其他函数接口才能够被正常使用。
正如图7中所示,在Dem_Init之前就调用Fim_GetFunctionPermission的函数接口,那么就会直接返回E_NOT_OK。
FiM功能模块作用过程
由上可知FiM模块的初始化过程以及EcuM,NVM,Dem,FiM几个模块之间的作用关系。接下来,我们重点关注FiM功能模块运作的核心部分过程,以便大家对FiM模块内部变量之间的变化关联有个清晰的了解。
图9 FiM功能模块作用过程
从上图中可以看出,可以将整个过程分为以下三个步骤:
S1:Dem模块调用FiM_DemTriggerOnMonitorStatus来通知FiM模块的Event
Status变化;
S2:FiM模块会紧接着调用Dem_GetMonitorStatus来获取最新的Event Status;
S3: SW-C模块则会调用FiM模块功能可用性接口FiM_GetFunctionPermission来轮询当前功能是否可用。 |