《AUTOSAR谱系分解(ETAS工具链)》之FIM

《AUTOSAR谱系分解(ETAS工具链)》之FIM


在这里插入图片描述

FiM模块简介

功能禁止管理器(Function Inhibition Manager)负责为软件组件及其功能提供控制机制。在这种情况下,功能组(Functionality)可以是由具有相同允许/禁止条件集的一个、几个或部分可运行实体(runnable entities)的内容构成。 通过FiM可以通过配置禁止这些功能组,甚至在运行时修改这些功能组使能或禁止。

功能组(Functionality)和可运行实体(Runnable Entities)是不同且独立的分类类型。可运行实体的主要特点是它们的调度要求。与此相反,功能组按其抑制条件分类(Inhibit Conditions)。FiM的服务专注于SW-C中的功能组,但是它们不仅限于这些功能组。BSW的功能组也可以使用FiM服务。

功能组可以被分配给一个标识符FID(Function Identifier),以及包含此特定标识符的禁止条件。功能组在执行前会通过各自FID来轮询许可状态。如果此特定标识符的禁止条件为真,则相应的功能组将不再被执行。

由于诊断事件及其它相关的状态信息可以用来支持这些禁止条件,所以FiM与Dem模块之间密切相关。在发生故障时,相关功能组会被停止运行。例如:特定标识符来标识的某种传感器,当它检测到故障,并将此故障事件(Event)报告给Dem,则FiM会禁止此FID,从而禁止相关的功能。

为了处理功能组之间的关系以及相关的事件,在配置过程中功能组的标识符和禁止条件被引入到SW-C模板中(BSW也类似)。通过这种方式,相关的数据结构会被建立起来,用来处理针对某些事件标识符的数据敏感性。

为了一些事件可以轻松配置,软件模块可以作为一个事件的集合被集成到一个新的环境中。 此外,当出现诸如“如果检测到特定事件时禁止哪些功能组?”之类的问题出现时,系统分析也能得到相关支持。FiM的数据基础,可用作事件和要禁止的SW-C之间配置关系的文档。

在AUTOSAR中,RTE根据已定义的接口和调度要求来处理SW-C。与此相反,FiM注意处理禁止条件,并提供相关支持机制实现通过相应的标识符(FID)来实现功能的控制。 因此FiM 模块的概念和RTE模块的概念其实是互不干扰的。

FiM模块功能概述

FiM模块的AUTOSAR标准文档为《.\SystemServices\AUTOSAR_SWS_FunctionInhibitionManager.pdf》

关于FiM模块功能概述如下:

  • FiM模块提供了一种基于抑制场景的功能降级策略,同时该抑制场景可配置;
  • 可通过特定的Function Identifier来实现相应的抑制场景;
  • 抑制场景可基于Dem模块的Event在FiM模块中根据降级需求完成映射;
  • FiM模块为BSW以及SW-C各模块的抑制场景提供了一种有效的降级手段;

简而言之,当SW-C或者BSW层发生故障发生时,会将故障即Event上报给到DEM模块,DEM模块会通过某种关系通知到FiM模块,FiM模块通过Function Identifier(以下简称FID)再次去告知SW-C以及BSW层做出相应的降级行为。

如下图所示,以SW-C模块上报故障为例,较为清晰了表示了彼此之间的作用关系:

在这里插入图片描述

其中,红色虚线表示上报故障Event,蓝色虚线表示广播FID状态。

基于上图,我们清楚了抑制场景可以通过Function Identifier(以下简称FID)来表示,某个抑制场景FID跟某个特定故障Event进行Mapping(即一对一关系),也可以是某个FID与多个Event进行Mapping(即一对多关系)。

在此有小伙伴可能会联想起Event与DTC也存在一对一或者一对多的关系。鉴于Dem模块与FiM模块密切相关,我便一并于此梳理下Event 、DTC、FID三者之间的映射关系,防止出现不必要的混淆。

如下图所示,描述了Event ID、DTC ID、DTC三者之间的映射关系:

在这里插入图片描述

注意:在图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。

如下图所示,描述了Event ID与FID之间的映射关系:

在这里插入图片描述

注意: 图中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模块用到的几个较为重要的参数在这里集中讲解一下

参数含义
FunctionInhibition某种抑制场景的表示
EventMonitorStatusEvent一个字节状态位 (与DTC Status一致)
InhibitionMASK导致FID置位的使能条件
FunctionldentifierCounter当前导致FID景位的Event数目

在上图中,我们看到有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模块内创建存储禁止关系(EventID – FID – 禁止掩码)的数据结构。

任意数量的EventId和禁止掩码可以分配给某一个FID,但每个FID的 EventId和禁止掩码的数量必须匹配。以便每个配置的事件,必然会存在一个对应的禁止掩码。

禁止掩码包含FID的禁止条件,前提是关联的EventId具有特定状态(Dem_EventStatusExtendedType)。这些掩码定义了FID对事件的哪些状态敏感。然而掩码不仅仅是根据Dem_EventStatusExtendedType来定位某些Bit位置,同时它更是从 Dem_EventStatusExtendedType中选择一种算法来计算抑制条件的布尔值。

禁止矩阵(Inhibit Matrix)可表现为每个禁止源 (即:EventId)的标定值的数据块。这意味着对于每个EventId,都有一组FID和掩码列表对应,他们需要被此EventId禁止。采用这种配置的FID状态数组的结构可参考下图。

在这里插入图片描述

每个FID都分配有一个禁止掩码,并且两者都分配给特定的EventId。如果此事件具有特定状态,则如果事件状态与配置的掩码匹配,则FID的禁止变为激活状态。

FiM模块可以提供通过Post-Build配置方式,提供修改禁止条件的可能性。

根据实施情况,Post-Build配置可能无法实现功能:

  • 添加新事件。
  • 扩展每个事件的禁止FID的数量。
  • 扩展有关事件数量、FID数量和连接数量的指定配置参数。

FiM模块交互关系

知道了FiM模块的主要功能,FiM又是如何与其他模块进行交互来完成其上述功能的呢?由于FiM模块做出相应Response的数据来源是Dem模块,我们首先来看看FiM模块与Dem模块之间的交互调用关系。

FiM模块与Dem模块交互关系

FiM模块的输入是来自Dem模块的Event Status,输出就是FID的状态。在此需要特别介绍几个参数取值如下:

Event Status:

诊断事件(Diagnostic Event)作为一种标识符,是为了Dem模块所提供的特定诊断监控功能用来报告错误的。

即之前文章讲到的一个Byte的Event status,每一个Bit代表相应的含义。

Monitor Status:

监控状态(Monitor Status)是Dem模块根据监控功能计算的报告状态。它可能的值由Dem_MonitorStatusType定义。

Monitored Component:

受监控组件(Monitored Component)作为一种标识符,是Dem模块提供标识特定受监控的组件,包括:硬件组件或者信号。受监控组件的FAILED状态代表所有被分配的监控功能和从其他Dem模块继承的故障信息的结果。

Summarized Event:

FiM配置可以支持汇总事件。汇总事件(Summarized Event)由多个单个诊断事件组成。

在配置过程中,一些单个事件可以组合成一个汇总事件(ECUC_FiM_00037)。汇总事件简化了对与此特定汇总事件相关联或由其表示的多个事件的处理。为了简化,SW-C模板可以使用此特定汇总事件作为禁止条件。

当与汇总事件相关联的某一个Dem事件被报告给FiM时,则FiM需要能够一并处理与该汇总事件相关联的所有FID的禁止条件。

因此特定的汇总事件只是作为多个诊断事件的代表。

例如:一个汇总事件可以用来表达某个传感器故障的所有错误条件的组合。

传感器X具有多个诊断功能。包括:短接到地、短接到电源和开路故障,分别用X_SCG、X_SCB和X_OC表示。当出现故障时,将禁用FID_0、FID_1、…、FID_N的功能。如果直接配置,则需要3 * N个FiMInhibitionConfiguration配置容器,包含FIM_INH_EVENT_ID = X_SCG/SCB/OC和FIM_INH_FUNCTION_ID = FID_0/…/N。

通过使用汇总事件配置(FiMSummaryEvent),可以将一组事件选择为FiMInhSumRef,并将其重用于多个抑制配置,最终以达到简化配置的目的。

Function Identifier Permission State

FID许可状态(Function Identifier Permission State)包含由FID表示的功能组是否可以执行的信息。如果许可状态为TRUE,则允许执行与FID关联的功能组。 如果许可状态为FALSE,则不允许执行与FID关联的功能组。

许可状态基于Dem报告的事件。因此许可状态不直接考量那些物理条件(例如:温度、发动机转速……),但这些物理条件需报告给Dem模块,让Dem报告相关的事件(例如:传感器缺陷)。

除了许可状态作为先决条件的之外,活动状态(当前某功能是否处于活动状态)包括物理使能条件,才是真正表示功能组是否确实被执行了(即:状态活动与否)。

如上所述,一种可能的实现是在状态变量中提供许可状态。另一种方法是基于底层依赖关系,在查询时计算许可状态。

提示: 如果许可状态存储在状态变量中,它们对于每个FID是唯一的。SW组件可以通过FiM_GetFunctionPermission来获取状态。

如果实现是使用状态变量来获得FID的许可状态,则在ECU的开发阶段,为了跟踪目的,可以使用标定系统读取此状态变量。

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;
Function Identifier:

FID全称Function Identifier,取值就是Bool类型 TRUE or FALSE,举例FID_1说明如下:

  • FID_1 == TRUE:即抑制场景不激活,功能不降级;
  • FID_1== FALSE:即抑制场景激活,功能降级。

FIM实现了功能权限的计算。这些计算的对象包括了那些接收“授权访问”和“拒绝访问”信息的软件模块和逻辑单元。

要定位这些组件,必须在FIM中模块中配置这些组件,并分配一个功能标识符(Function Identifier)使可以通过接口来定位到它们。

配置过程应保证FiM的每个FunctionId是唯一的。对事件具有不同依赖性的两个不同功能组永远不会具有相同的FunctionId。

FiM模块的环境应使用FunctionId直接指向相关的功能组信息(权限状态等)

信息流从提供事件信息更改的Dem的API调用开始。信息被处理后,相关依赖的FID会被评估。

最后,FID的权限状态通过通过API访问经过RTE层返回:

在这里插入图片描述

每个FID的权限状态是根据分配给特定FID的EventId计算的。接着每个计算出的FID(例如:FID_K)的权限状态再进行一个与(AND)的运算,以确定最终的权限状态。 这意味着在实现时FiM会将FID的权限状态存储在RAM中。

FiM也可以轮询监视器状态,以重新计算权限状态。轮询可由请求权限状态的功能组(SW-C或BSW)触发,也可以在周期性任务中。在这种情况下,任何事件发生变化时,FiM模块都无需增加处理的工作量。

FID Counter:

用于表征当前存在几个Event同时发生导致了该类型的抑制场景激活,进而功能降级。

Event Status与Inhibition Mask、FID、FID Couner之间的计算关系:

如下图所示,表示了来自Dem模块的Event Status,与FiM模块中的Inhibition Mask、FID、FID Couner这四者之间的计算关系;

在这里插入图片描述

由图可知Event ID的状态与Inhibition MASK是位与的关系,如果位与的结果为1,那么相应Mapping 的FID Counter就会加1。其中每个FID只能选择其中一种类型Inhibition MASK,这个是在工具中静态配置,不支持动态更改。

如果多个Event ID发生且与Inhibition MASK位与的结果为1时,那么FID Counter又该如何表现呢,如下图所示:

在这里插入图片描述

如上图所示,假设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 如何变化呢?

在这里插入图片描述

当Event A Status & Ihibition MASK = TRUE, FID_A Counter++, 即FID_A Counter = 1, FID_A = FALSE;
当Event B Status & Ihibition MASK = TRUE, FID_A Counter++, 即FID_A Counter = 2, FID_A = FALSE;
当Event C Status & Ihibition MASK = TRUE, FID_A Counter++, 即FID_A Counter = 3, FID_A = FALSE;
过一段时间Event C Status & Ihibition MASK = FALSE, FID_A Counter–, 即FID_A Counter = 2, FID_A = FALSE;
同上,EventB Status & Ihibition MASK = FALSE,FID_A Counter–, 即FID_A Counter = 1, FID_A = FALSE;
同上,EventB Status & Ihibition MASK = FALSE,FID_A Counter–, 即FID_A Counter = 0, FID_A = TRUE;
通过上述场景分析得知,只要FID_A Counter不等于0,FID_A 就会等于FALSE,系统就会降级。不过在此需要特别提醒的是虽然此时你知道系统降级了,但是从FID你无法知道到底是哪个Event导致的降级,此时就需要通过相关的诊断服务读取内部的Event并且该Event也确实Map了该FID,那么你就可以锁定该Event就是原因所在。

Dem和FiM之间的交互

FiM模块提供的服务可以实现通过Dem事件作为禁止条件来允许或者禁止SW-C的相关功能组。

功能禁止管理器需使用软件组件提供的FID-EventID-Inhibition Masks关系来确定所有已配置FID的许可状态。

在需报告事件的监控状态发生变化时,并启用了DemTriggerFiMReports,则Dem通过API函数FiM_DemTriggerOnMonitorStatus通知FiM监控状态已经变化。

在收到有关监视器状态(Monitor Status)更改的通知后,FiM模块可以通过API函数Dem_GetMonitorStatus重新计算功能禁止。

注意: 从功能实现的角度来说,禁止/释放条件的同步更新可以在FiM_MainFunction函数里或在其他函数中实现。

FiM模块的实现高度依赖于应用程序的要求(例如:时序上的要求)。如果应用程序需要快速响应,则FiM必须足够快地提供FID信息,以允许触发limp-home的功能。

FiM_DemTriggerOnMonitorStatus函数仅在每个FID的状态变量被保存时才相关。 当没有状态被保存时,并且每次权限状态被查询时都会计算,则FiM_DemTriggerOnMonitorStatus应无任何效果。

如下图所示,当单个EventId和FID关联计算时,首先左侧的监视器状态(Dem_EventStatusExtendedType)会由Dem模块负责报告,接着报告的状态需要和EventId配置的掩码的Bit位进行依次地比较。

在这里插入图片描述

每个FID会被分配一个禁止计数器(Inhibition Counter)。此禁止计数器包含当前禁止的EventId的数量。计算是周期性执行的(可通过Dem_GetMonitorStatus读取监控状态)。当状态和掩码匹配时,则禁止计数器会增加,否则禁止计数器不会更新。此算法同时适用于FiM_GetFunctionPermission函数(如果必须根据查询计算权限状态)和 FiM_MainFunction函数。

在监视器状态变化的触发中,当前禁止事件ID(Inhibiting EventId)存储的禁止计数器,将会被用于许可状态的计算。当FiM_DemTriggerOnMonitorStatus报告了监视器状态变化,需执行以下操作:

  • 如果EventId的状态变化导致释放状态(released state),即掩码与监视器状态不匹配,则禁止计数器需要递减。
  • 如果EventId的状态变化导致禁止状态(inhibited state),即掩码与监视器状态匹配,则禁止计数器需要递增。

在这里插入图片描述

如果禁止计数器大于0,则FID许可状态应设置为FALSE,否则FID许可状态应设置为TRUE。

FiM模块应根据禁止源(inhibit source)的实际状态和此禁止源的被标定掩码进行禁止状态的计算。如果监视器状态等于被标定掩码(包括:Defect、Tested、NotTested),FiM模块应禁止FID。

如果事件的掩码不再与被标定值匹配,则取消FID的禁止。测试状态可以被用于表示禁止条件。根据禁止条件,如果事件的状态为已测试(Tested)或未测试(NotTested),禁止则可以被激活。如果未选择测试值,则测试状态不相关。

状态标志的各种可用组合可以被分配给某个预定义值,诸如:Tested、Not_Tested或Last_Failed的表示。

功能禁止管理器应使用FID - DemComponentId - 禁止配置,来确定已配置FID的许可状态。当Dem模块的FAILED状态发生变化时,应重新计算功能状态。只要组件状态为FAILED(即:ComponentFailedStatus = TRUE),则FID就需被禁止。

如果FIM配置为周期性轮询状态,则FIM需调用Dem_GetComponentFailed来获取组件的当前FAILED状态。

如果FIM配置为基于eventStatus(即:FiMCyclicEventEvaluation)触发,则FIM应通过提供函数FiM_DemTriggerOnComponentStatus来接受Dem模块的状态变化信息。

FiM模块与SW-C模块交互关系

如下图所示,FiM模块的FID 状态最终需要给到各个SW-C层模块使用,SW-C模块通过主动去询问所需要检查的FID状态,来做出相应的系统降级行为。

在这里插入图片描述

上图实际上可以理解为图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之间的交互

FiM模块需为每个FID禁止条件提供处理提供配置机制。并且使用软件组件模板内容的FiM的配置机制可以通过标定来进行修改。

具体的配置步骤如下:

  • 引入并分配FID。
  • 对于每个FID,软件组件应提供导致FID被禁止的事件列表以及相关掩码。

在配置过程中,相关数据结构会被建立起来。这数据结构可以是一个事件(event)到所有受影响的FID的映射。或者反之亦然,一个FID到影响它的所有事件的映射。软件模块通过AUTOSAR服务来查询FID的权限状态。

FiM模块需确保通过同步响应传入的权限查询能立即控制相关功能。FiM模块需通过将许可状态存储为状态变量,或者通过在权限查询时评估事件的状态。

如果使用接口FiM_SetFunctionAvailable将功能(即:FID)设置为不可用,则其权限状态FiM_GetFunctionPermission会始终返回FALSE。

FiM模块主要函数调用接口

从上面的讲解中,相信大家对Dem、FiM、SW-C、Error Management 这四个模块之间的作用关系有了较为清晰的了解。接下来我们就来重点看下FiM模块与其他模块之间的主要的函数调用接口是如何使用的,以便让我们日后在调试问题的过程中,遇到系统降级的问题,有一个较为清晰的思路去理解中间的数据流,快速定位问题所在。

FiM_Init:

该函数是为了完成FiM相关结构体的初始化工作。如果DET模块使能,可以判断FiM模块是否初始化成功,或者可以通过一个静态变量是否发生变化来判断有无初始化完成。

因为如果FiM模块没有完成初始化,就被其他模块调用其内部的函数,就会返回E_NOT_OK,所以调用FiM其他函数接口之前必须完成FiM模块的初始化。

void FiM_Init (
    const FiM_ConfigType* FiMConfigPtr
)

FiM_DemInit

该函数逆初始化FIM。

void FiM_DemInit (
    void
)

FiM_DemTriggerOnMonitorStatus:

该函数是为了提供给Dem模块当Event Status发生变化时通知到FiM模块的接口。一旦Event Status 发生变化,Dem就会主动调用该函数,通知FiM,这本质上就是一种Trigger Action行为。

其实FiM获取Event Status状态变化,还有一种方法就是polling方式,但是Polling方式有一个缺点,当Event数目比较大时,有时候就无法察觉到某些Event Status的快速变化,所以一般而言,都优先选择这一种Trigger 方式来完成对FiM模块的Event Status 通知。

void FiM_DemTriggerOnMonitorStatus (
    Dem_EventIdType EventId
)

FiM_GetFunctionPermission:

该函数是为了提供给SW-C或者BSW模块来获取FID的状态。如果请求的FID超出范围,那么FID就会直接返回FALSE。如果FiM模块还没有初始化完成,同理,调用该函数也会直接返回FALSE。

Std_ReturnType FiM_GetFunctionPermission (
    FiM_FunctionIdType FID,
    boolean* Permission
)

FiM_SetFunctionAvailable:

该函数用来给BSW或者SW-C层来设置某功能是否可用,如果输入参数为TRUE,那么该功能可以正常使用;若输入参数为FALSE,则该功能就会被Disable。

如果使用接口FiM_SetFunctionAvailable将功能(即:FID)设置为不可用,则其权限状态FiM_GetFunctionPermission会始终返回FALSE。

Std_ReturnType FiM_SetFunctionAvailable (
    FiM_FunctionIdType FID,
    boolean Availability
)

FiM_GetVersionInfo:

该函数返回该模块的版本信息。

void FiM_GetVersionInfo (
    Std_VersionInfoType* versioninfo
)

FiM_MainFunction:

该函数是为了实现对Event Status与Inhibition MASK的计算,此处有两种方式,一种就是Polling方式,另外一种就是Event Trigger方式,这两种方式的使能通过工具选项FiMEventUpdateTriggeredByDem 是否为TRUE决定。

void FiM_MainFunction (
    void
)

FiM模块函数调用关系

基于上述函数的理解,我们来进一步重点看看FiM模块的初始化过程以及FiM跟随Event Status变化的函数调用过程。在理解函数调用关系的基础上,为我们实现代码调试、软件编写将起到相应的辅助作用。

FiM模块初始化过程

如下图所示,表示了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模块就最终完成了初始化,其相关其他函数接口才能够被正常使用。

正如上图中所示,在Dem_Init之前就调用Fim_GetFunctionPermission的函数接口,那么就会直接返回E_NOT_OK。

FiM功能模块作用过程

由上可知FiM模块的初始化过程以及EcuM,NVM,Dem,FiM几个模块之间的作用关系。接下来,我们重点关注FiM功能模块运作的核心部分过程,以便大家对FiM模块内部变量之间的变化关联有个清晰的了解。

在这里插入图片描述

从上图中可以看出,可以将整个过程分为以下三个步骤:

S1: Dem模块调用FiM_DemTriggerOnEventStatus来通知FiM模块的Event Status变化;

S2: FiM模块会紧接着调用Dem_GetEventStatus来获取最新的Event Status;

S3: SW-C模块则会调用FiM模块功能可用性接口FiM_GetFunctionPermission来轮询当前功能是否可用。

FiM的应用示例

在这里插入图片描述

FiM的配置实际上建立在事件EventId和分配的功能FunctionId的关系之上。

CAN10_BUS_OFF功能抑制配置参考:

  • 软件通过Dem_SetEventStatus函数设置Event的请求;

      if((CAN10_PSR_LEC() == 3U) && (CAN10_ECR_TEC() == 128U))
      {
        if(CAN10_PSR_LEC_ture_Cnt < 20U)
        {
          CAN10_PSR_LEC_ture_Cnt++;
        }
        else
        {
          Dem_SetEventStatus(DemConf_DemEventParameter_MAIN_CAN10_BUS_OFF,DEM_EVENT_STATUS_FAILED);
          CAN10_Ackerror_flag = 1;
        }
      }
      else
      {
        CAN10_PSR_LEC_ture_Cnt = 0;
        CAN10_Ackerror_flag = 0;
        // CAN10_PSR_LEC_false_Cnt++;
        if (GetCanApp_Can_BusOffSts(ComMConf_ComMChannel_ComMChannel_Can_Network_0_Channel) == CeCAND_BUSOFF)
        {
          Dem_SetEventStatus(DemConf_DemEventParameter_MAIN_CAN10_BUS_OFF, DEM_EVENT_STATUS_FAILED);
        }
        else
        {
          Dem_SetEventStatus(DemConf_DemEventParameter_MAIN_CAN10_BUS_OFF, DEM_EVENT_STATUS_PASSED);
        }
      }
    
  • Dem模块通过debounce等配置设置Event的状态位;

  • FIM模块通过查询DEM模块的Event的状态设置FID的状态;

    在这里插入图片描述

  • SWC通过FiM_GetFunctionPermission函数查询FID的状态,而后控制SWC功能的抑制状态;

    在这里插入图片描述

ISOLAR配置参考

在这里插入图片描述

FiMConfigSet
  • FiMFID

    在这里插入图片描述

    参考的DEM的DemEventParameter:

    在这里插入图片描述

  • FiMInhibitionConfiguration

    在这里插入图片描述

  • FiMSummaryEvent

    在这里插入图片描述

FiMGeneral_0

略。

一些FIM相关的AUTOSAR代码示例:
/**
**************************************************************************************************
 * macros for inhibition mask checks acc. to chapter 10.2.7
**************************************************************************************************
 */
#define FIM_LAST_FAILED_MASK        0x01    /* TF */
#define FIM_LAST_FAILED_VALUE       0x01    /* TF */
#define FIM_NOT_TESTED_MASK         0x40    /* TNCTOC */
#define FIM_NOT_TESTED_VALUE        0x40    /* TNCTOC */
#define FIM_TESTED_MASK             0x40    /* TNCTOC */
#define FIM_TESTED_VALUE            0x00    /* !TNCTOC */
#define FIM_TESTED_AND_FAILED_MASK  0x41    /* TNCTOC&TF */
#define FIM_TESTED_AND_FAILED_VALUE 0x01    /* !TNCTOC&TF */

#define FIM_INHIBITION_BITS_MASK    0x41 /* (LAST_FAILED_MASK|NOT_TESTED_MASK|TESTED_MASK|TESTED_AND_FAILED_MASK) */

#define FIM_PENDING_BITS_MASK       0x04
#define FIM_PENDING_BITS_VALUE       0x04
const uint16 SysDrgd_FidReaction_Cfg[SYSDRGD_REACTION_NUMMAX][FIM_CFG_NUMBEROFFIDS] =

{
  //SYSDRGD_REACTION_RESET_MCU
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },
  //SYSDRGD_REACTION_SHUTOFF_PMIC
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },
  //SYSDRGD_REACTION_RESET_SOC
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },
  //SYSDRGD_REACTION_SHUTOFF_ALLCOMM
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },

  //SYSDRGD_REACTION_SHUTOFF_ASWCOMM
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },

  //SYSDRGD_REACTION_LKA_OFF
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },

  //SYSDRGD_REACTION_AEB_OFF
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  },
  //SYSDRGD_REACTION_ACC_OFF
  {
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  }
};

#include "FiM_Types.h"

/*  short name           FId value */
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    #define FiMConf_FiMFID_FID_CAN0_BUSOFF    (6)
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#define FIM_CFG_NUMBEROFFIDS  (86) 
#define FIM_CFG_INVALIDFID  (0)
CONST (FiM_FunctionIdType, FIM_CONST) FiM_CfgInhibitSourceMatrix_au16[FIM_CFG_MAX_TOTAL_LINKS_CALC] =

{
  /* <----- Fim_FIds -----> */ 
  /* DemConf_DemEventParameter_CANSM_E_BUSOFF_NETWORK_0  0 - 0 */  
  FiMConf_FiMFID_FID_CAN0_BUSOFF
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
};
#include "Std_Types.h"

/**
\* @ingroup FIM_TYPES_H
\* @typedef FiM_FunctionIdType
\* @brief Holds a function ID. The size depends on the total amount of function IDs.
*/

typedef uint16 FiM_FunctionIdType;
CONST ( FiM_ConfigType, FIM_CONST ) FiMConfigSet =

{
  FiM_Cfg_NumOffsetEvent_auo,
  FiM_CfgInhibitSourceMatrix_au16,
  FiM_CfgInhibitMaskMatrix_au16
};
FiM_Init(&FiMConfigSet);

《AUTOSAR谱系分解(ETAS工具链)》之总目录

《AUTOSAR谱系分解(ETAS工具链)》之总目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值