文章包含了AUTOSAR基础软件(BSW)中BswM模块相关的内容详解。本文从AUTOSAR规范解析,ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解BswM这一基础软件模块。文中涉及的SOLAR-AB配置以及模块相关代码都是依托于ETAS提供的工具链来配置与生成的,与AUTOSAR规范之间可能会有些许的出入,但总体的功能要点与处理流程都应该是一致的。
BswM基础模块可谓是整个基础软件的大管家,它是一个可以宽泛定义的“状态机”,根据对当前软件状态的仲裁来执行对应的动作。它可以简单分为在应用正常运行前的基础软件初始化与启动,应用正常运行中的模式切换处理(来源可以是应用软件组件或者基础软件组件)这两个部分,模式切换可以直接导致整个基础软件的关闭以及EcuM关闭动作序列的执行。
AUTOSAR规范解析
BswM(基础软件模式管理器)基本的功能的主要涉及两个方面:Mode Arbitration(模式仲裁)和Mode Control(模式控制)。
模式仲裁负责判断模式切换条件,若满足则执行模式切换动作,该切换是对从SWCs(软件组件)或其他BSW模块(基础软件)接收到的Mode Requests(模式请求)和Mode Indications(模式通知),根据集成商配置的组合判断逻辑进行仲裁而产生的。模式控制部分通过执行包含其他BSW模块模式切换操作的动作列表来执行模式切换。
BswM应被视为一个模式管理框架模块,涉及的模式逻辑判断和执行动作完全由集成商的配置来定义。
模式仲裁
BswM执行的模式仲裁是基于规则的,规则由简单的布尔表达式组成。用于模式仲裁的规则在BswM模块的配置中指定。
仲裁规则(Arbitration Rules)
规则是由一组模式条件组成的逻辑表达式,并绑定了判断结果与对应的操作列表。当模式请求或模式通知由SWCs或BSW模块通知BswM更改时,BswM将评估这些规则。评估的执行可以是立刻的或者在BswM主函数的执行过程中,评估结果(真或假)用于决定是否执行相应的模式控制操作列表。
模式状态和逻辑表达式(Mode Conditions and Logical Expressions)
包含模式仲裁规则的逻辑表达式可以使用不同的操作符,如AND、OR、XOR,NOT和NAND。表达式中的每个项都对应一个“模式状态”,它引用标识SWCs和BSW模块不同的子模式。模式分为两种类型:
- BswMModeRequestPort:如果条件引用BswMModeRequestPort,条件将验证当前的模式是否与某个特定模式一致。
- BswMeventRequestPort:如果条件引用BswMeventRequestPort,条件将验证请求端口是SET还是CLEAR,它跟BswMModeRequestPort相比并不需要评估模式的状态,BswM在评估完成之后,将BswMeventRequestPort通过BswMClearEventRequest将其置为CLEAR状态。
下图的仲裁规则的逻辑表达式判断了某个模式状态为MODE_A并且ComM已经被重新初始化,根据其真值表,执行对应的动作列表。
模式仲裁来源
BswM接受模式请求和模式通知作为模式仲裁的来源。模式请求通常来自应用程序SWCs,但也可能来自BSW模块,如DCM。模式通知总是由其他BSW模块发出,如不同的专用状态管理器CANSM、EcuM和WdgM等,他们通过BSW提供的接口来通知BswM模式的改变,例如BswM_ComM_CurrentMode这个API会与BswMComMIndication的Request Port进行映射,ComM管理的某个通道在状态发生改变的时候,就会通过BswM_ComM_CurrentMode这个API来通知BswM,集成商通过BswM的BswMModeRequestPort中的BswMModeRequestSource来映射。
在文中,模式仲裁请求对应于模式请求或模式通知。模式请求和模式通知都是以同等的地位在BswM中接收仲裁,且这两种类型都可以在AUTOSAR标准配置项BswMModeRequestSource得以体现。笔者建议读者现在可以先不要区分模式请求和模式通知的区别,就先记得他们都是触发BswM模式切换的源头就可以了,具体的区别可以在后边的配置以及代码分析章节来理解具体区别。
在BswMModeRequestPort中,可以配置两种方式去处理这些请求。
- Deferred:该模式下,规则的仲裁(包括行为的执行)会在BswM的BswM_MainFunction函数(周期调用)中去处理。
- Immediate:在该模式下,规则的仲裁会在请求/通知者的上下文环境立刻执行。
BswM初始化后的模式仲裁行为由BswMModelnitValue控制。这个参数可以为每个BswMModeRequestPort配置,大多数情况下控制项可以留白,将会导致仲裁结果未定义。BswMRulelnitState来配置规则的默认值,其在重启的时候被认为是“上一次的仲裁结果”,绝大多数情况下为FALSE。
模式仲裁整体结构
上面介绍完了模式仲裁过程中的三大构件(模式请求输入、逻辑表达式、仲裁规则),下图展示了它们之间的引用关系,它们相互引用组合,完成了BswM的仲裁工作。
模式控制
模式处理
下面介绍一下最简单的模式处理流程,它介绍的请求来源为SWCs。
- 模式请求者SW-C通过其PPort请求模式A。RTE分发请求,BswM通过它的RPore接收它。
- BswM会根据收到的模式仲裁请求,在请求的上下文直接或在周期执行的BswM_MainFunction对其涉及规则进行评估。
- 根据所选的执行方法执行相应的操作列表。
- 当执行动作列表时,BswM可能会发出一个或多个对RTE Switch API的调用,作为通知受影响的SWCs仲裁结果的行动。任何SWCs,特别是模式请求者可以注册以接收模式切换指示。(可选用,一般集成商未用到)模式请求者只能从本地BswM接收模式切换指示。
有时需要延迟特定操作或等待进一步的模式控制。出于这个原因,在BSWM中添加了一个Timer处理。这块在框架下实现的情况比较少,这里就不赘述了。
操作执行
在模式控制的配置选项中,一般会存在BswMAction与BswMActionList两类选项:
- BswMAction: 则用来配置各种各样标准的行为;(如Com模块报文切换等)。
- BswMActionList: 用来定义BswMAction的集合。
操作列表(BswMActionList)的执行方法是使用 BswMActionListExecution 参数(在 BswMActionList容器中)配置的。
- CONDITION:只要模式仲裁规则成立,一直连续不断的执行。
- TRIGGER:仅在模式规则的逻辑值发生变化(未定义变成True),才会去执行相应的ActionList。
下表展示了不同的执行方法与“上一次判断结果”组合下的不同ActionList执行情况。
可以通过配置参数BswMAbortOnFail结果为TRUE,来达到当Action执行返回值为E_NOT_OK,终止列表剩余动作的执行。
BswM Interfaces and Ports
这部分内容是AUTOSAR标准包含的,其中涉及BswMSwitchPort以及BswMRteModeRequestPort部分,ETAS出于中心化的考虑,大部分的基础软件例程都很少采用这部分框架来实现功能。但是,这其中包含了AUTOSAR基础软件模式管理的一些理念,笔者这边还是简单介绍一下。
本节主要介绍了软件模式管理器提供的AUTOSAR接口和端口,请注意,端口需要成对出现方能连接,软件模式管理器提供的端口在RTE下侧。
针对SWCs模式请求的实现,应用组件提供一个发送端口,其中包含一个数据元素。BSW模式管理器中相应的接收器端口使用在SW-C定义的Interface,Interface中的数据元素的类型必须一致,才能完成端口的连接。
RequirePort AppModeRequestInterface modeRequest-Port_{ArbName}_{ReqName};
为了获取当前的请求模式, BSW模式管理器必须调用如下函数。
Rte_Read_modeRequestPort_{ArbName}_{ReqName}_requestedMode(&<variable>);
请求模式的同一个SW-C也可能是模式用户,因为它也可能需要知道BSW模式管理器的仲裁结果。SW-C有一个Mode Switch Port,它是一个使用Mode Switch Interface的R端口,带有一个数据元素。这个数据元素的类型就是Mode DeclarationGroup本身。此外,其他不请求模式,但依赖于此模式的SWCs也有这样的Mode Switch Port。下面为一个RequirePort定义。
RequirePort AppModeInterface modeNotificationPort_{ArbName}_{ModeName};
为了获取当前的模式,BSW模式管理器必须调用如下函数。
Rte_Mode_modeNotificationPort_{ArbName}_{ModeName}_currentMode( &<variable> );
SchM_Mode_modeNotificationPort_{ArbName}_{ModeName}_currentMode( &<variable> );
当模式管理器切换相应的模式时,RTE将发送模式通知。为此,BSW模式管理器有一个Provided type的Mode Switch Port,SWCs可以连接到该端口。下面为一个ProvidePort定义。
ProvidePort AppModeInterface modeSwitchPort_{ModConName}_{SwitchName};
为了改变当前的模式,BSW模式管理器必须将下列的函数插入ActionsList中。
Rte_Switch_modeSwitchPort_{ModConName}_{SwitchName}_currentMode( <new_mode> );
SchM_Switch_modeSwitchPort_{ModConName}_{SwitchName}_currentMode( <new_mode> );
在请求SW-C的上下文中,定义了模式请求端口(发送方/接收方)。BSW模式管理器的配置引用此端口定义。 让我们假设SW-C定义了一个应用程序模式:AppModeType,并定义了对应的AppModeRequestType和把两种类型相互映射的AppModeTypeMap。
ModeDeclarationGroup AppModeType {
{ APP_MODE_A, APP_MODE_B, APP_MODE_C }
initialMode = APP_MODE_A;
};
ImplementationDataType AppModeRequestType {
lowerLimit = 0;
upperLimit = 2;
};
ModeRequestTypeMap AppModeTypeMap {
modeGroup = AppModeType;
implementationDataType = AppModeRequestType;
}
在SW-C的上下文中,定义了两个接口:
- AppModeRequestInterface:Sender/Receiver类型,SW-C为Sender。
- AppModeInterface:Mode Switch 类型,SW-C可以拥有此类型对应的发送/接收端口。
下图显示了应用程序SWCs的端口如何连接到BSW模式管理器。图中的SW-C(应用程序模式管理器)有一个模式请求端口和一个模式切换R端口(命名为modeNotificationPort,以区别于模式切换P端口)。第一个端口用于请求更改模式状态,后一个端口用于在BswM执行模式更改时接收通知。
Component Type and Internal Behavior
BSW模式管理器是服务ECU本地模式请求的服务组件。BSW模式管理器的ServiceComponentType声明所有上述端口和一些内部行为。
ServiceComponentType BswM {
...
InternalBehavior {
...
};
};
BswM内部行为取决于BswMModeRequestPort中选择请求处理方式是Deferred还是Immediate,一个立即处理模式请求需要在BswM中的内部行为增加下列声明,RTE才能立刻触发模式仲裁。
RunnableEntity ModeArbitrationRunnable {
symbol = <mode_arbitration_function>;
canBeInvokedConcurrently = TRUE;
};
DataReceiveEvent AppModeRequestEvent {
port = modeRequestPort0;
dataElement = requestedMode;
startOnEvent = ModeArbitrationRunnable;
};
ISOLAR-AB配置
Software
首先建立一个名为MDG_ECUM_STATE的ModeDeclaration如下。
然后将模式映射到具体的实现类型uint8。
建立一个Interface,用于应用层组件项BswM请求模式。
在Test1下方建立Pport口,Interface采用SenderReceiverInterface_uint16,接口的VDP是VDP_uint16,根据这个数据原型能够跟BswMModeRequestPorts进行连接,从而完成BswM状态请求。
然后在Test1的Functions添加数据的访问,这样就可以生成访问RTE的接口,把模式发送给RTE。
BswM
BswM模块涉及的配置分类为BswMGeneral以及BswMConfig,BswMConfig下边又包含了BswMArbitration、BswMDataTypeMappingSets以及BswMModeControl。
BswMGeneral
General下边包含了一些BswM的通用配置,首先我们如下图所示,可以增加一下需要包含的头文件。
上图的配置会在BswM_Cfg_AC.c等文件中增加下列头文件包含声明。
/* User Include Files */
#include "Rte_Main.h"
剩下的配置则是BswM模块涉及到其他模块则需要选择ture,其余的配置在Quick Info中都有对应的解释,并不难理解。
BswMModeRequestPorts
我们这里建立三类ModeRequestPorts来举例说明不同模式切换来源。
首先是来自BswM模块自身的模式切换端口,它引用了在Software中定义的模式MDG_ECUM_STATE定义。
其次是来自应用层软件的模式切换请求,它的数据类型为应用层定义好的Interface对应的VDP。
最后是来自其他BswM模块的模式切换通知,下图中的示例来自DCM,针对28服务(CAN通信启停)完成对ComMode切换的请求。
BswMModeConditions
针对上述提到的三个模式接口,我们定义五种模式状态。
BswM_MC_BswM_StartupOne定义为与之前定义的MDG_ECUM_STATE模式中的ECUM_STATE STARTUP_ONE状态,BswM_MC_BswM_StartupTwo定义为与之前定义的MDG_ECUM_STATE中的ECUM_STATE STARTUP_TWO状态。来源是BswM模块自身的模式切换。
BswM_MC_BswM_PostRun定义为与之前定义的MDG_ECUM_STATE模式中的ECUM_STATE_POST_RUN状态,来源为应用层软件组件。
BswM_MC_DCM_ENABLE_RX_TX_ALL为Dcm模块定义的Dcm_CommunicationModeType中的DCM_DISABLE_RX_ENABLE_TX_NORM_NM状态,BswM_MC_DCM_DISABLE_RX_TX_ALL为Dcm模块定义的Dcm_CommunicationModeType中的DCM_ENABLE_RX_DISABLE_TX_NORM_NM状态,来源为Dcm模块。
BswMLogicalExpressions
逻辑表达式这个部分可以引用多个BswMModeConditions,并在之间选择AND或者OR等条件逻辑符,我们这里就引用了一个BswMModeConditions,就不用选了。
BswMActions
我们这里只定义了五个动作,包含了BswM模式切换,其余基础模块模式切换,以及用户自定义函数调用。
BswM_AI_BswMSwitchStartupTwo实现切换到ECUM_STATE STARTUP_TWO状态动作。
BswM_AI_BswMSwitchRun实现切换到ECUM_STATE_RUN状态动作。
BswM_AI_DCM_ENABLE_RX_TX实现启动PDU Group收发。
BswM_AI_DCM_DISABLE_RX_TX实现停止PDU Group收发。
BswM_AI_GoDown调用用户自定义的函数,为EcuM模块提供的BswM_AI_GoDown函数,传入的参数为EcuM模块配置的EcuMFlexUser。
BswMActionLists
在应用程序运行之前,相应的基础软件应该都已经就绪,一般需要涉及以下启动动作:
- Fee_Init:FEE(Flash EEPROM Emulation)模块初始化。
- NvM_Init:NVM即Non-VolatileRAM Manager (NVRAM Manager),用于管理存储于各类non-volatile memory(如EEPROM/flash等)的数据。
至此,在之前EcuM完成的Fls_17_Pmu_Init的基础上,整个存储协议栈完成了初始化。接下来将存储的数据读取出来:
-
NvM_ReadAll:初始化所有NVRAM块的管理数据,将EEPROM/flash等数据复制到永久RAM块,或为相应配置的NVRAM块调用显式同步回调(NvM_ReadRamBlockFromNvm)。、
-
NvM_ReadBlock:将NVRAM块的数据复制到用户提供的变量地址处的服务。
然后,物品们把其他的基础软件进行初始化。
- CanIf_Init:初始化CanIf模块。
- CanTp_Init:初始化CanTp模块。
- CanSM_Init:初始化CanSM模块。
- PduR_Init:初始化PduR模块
- Com_Init:初始化Com模块
- Dcm_Init:初始化Dcm模块
- ComM_Init:初始化ComM模块
- Dem_Init:初始化Dem模块
-
Xcp_PreInit & Xcp_Init:初始化Xcp模块
至此,通信协议栈、诊断、XCP的初始化均已完成,然后启动系统Timer并调用Rte_Start,系统调度正式启动。最后我们将具体的基础软件状态推到正确的状态,为应用程序启动做准备。
- StartPdu:启动Pdu Group收发。
- ComMAllowCom:使能ComM定义的相应通信通道。
- ComMModeSwitch:切换ComM定义的相应通信通道为BSWM_FULL_COM。
至此,通信已经启动,可以调用应用相应的初始化动作,应用程序启动,BswM切换到一个不执行具体动作的空状态,Ecu控制权交给应用程序。
我们的例程没有执行这么多行为,我们只是将刚才定义的BswM_AI_BswMSwitchStartupTwo与ECUM_STATE_RUN分别包含为两个BswMActionList,只做了模式的切换示例,并未执行上述的这些初始化动作。
BswM_AL_BswMStartupOne完成切换到ECUM_STATE STARTUP_TWO,BswM_AL_BswMStartupTwo完成切换到ECUM_STATE_RUN。
下面介绍的动作列表为BswM_AL_DCM_ENABLE_RX_TX与BswM_AL_DCM_DISABLE_RX_TX,它们包含对应的启动/停止 Pdu Group的收发,完成诊断28服务对通信口的控制。
最后,经过应用层传过来进入ECUM_STATE_POST_RUN请求,BswM要执行关闭动作:
- ComMAllowCom:失能ComM定义的相应通信通道。
- ComMModeSwitch:切换ComM定义的相应通信通道为BSWM_NO_COM。
- StartPdu:停止Pdu Group收发。
- Dem_Shutdown:Dem_Shutdown应完成Dem模块中的所有未决操作,以准备内部状态和数据,以便传输至NVRAM。
-
NvM_WriteAll:函数NvM_WriteAll的作业应将永久RAM块的内容同步到它们相应的NV块上,或者在关闭时调用显式同步回调(NvM_WriteRamBlockToNvm)。
-
CanTransciverSleep:如果有必要,将CAN收发器置于休眠模式。
-
Rte_Stop:关闭RTE。
-
ComM_DeInit:取消通信管理器初始化。
-
EcuM_GoDown:将EcuM推到Down阶段。
-
EcuM_MainFunction:执行EcuM的Down阶段行为。
-
SbcShutdownFunc:如果有必要,将电源芯片置于Standby模式。
我们的示例,与启动一样,也没有执行这么多的行为,仅仅包含了EcuM_GoDown的执行。
BswMRules
最后,我们通过仲裁的Rules将逻辑表达式LE和动作列表AL绑定到一起,这样就能根据逻辑表达式的真值表来执行对应的动作列表。对应绑定关系如下图。
BswMDataTypeMappingSets
我们还需要把之前在Software中定义的模式映射关系引用到BswM中,这样在生成BswM的BSWMD的过程中就能生成引用到这个模式对应的端口。
System
首先我们需要完成BSW的生成动作,配置如下。
这样我们就能在软件组件下面看到BswM这个服务组件,组件内的配置均已根据之前我们进行的BSW配置自动生成好了。
然后我们需要把服务组件加入部件。
把软件组件加入ECU。
最后,我们完成Test1到BswM组件的连接,完成后如下图。
OS
建立Task名为BSW_OsTask_SwcRequest,其不需要调度,任务由RTE激活,执行BswM本地的模式请求。
RTE
将BswM服务组件涉及的运行实体添加到任务中,例子中涉及:
- BswM_MainFunction:调度表周期激活,映射到周期调度任务。
- BswM_Cfg_DfrdSwcReqst_BswM_MRP_SwcModeRequest:RTE激活,映射到之前OS定义的BSW_OsTask_SwcRequest任务。
- BswM_Cfg_DfrdBswNotification_BswM_MRP_BswM_MDG_ECUM_STATE_STARTUP_ONE与BswM_Cfg_DfrdBswNotification_BswM_MRP_BswM_MDG_ECUM_STATE_STARTUP_TWO:由SchM(现在已经与RTE整合到一起)根据BswM调用传入不同的模式进行调用。
最后,我们需要完成SchM(现在为RTE)到BswM的模式端口连接,连接完成之后BswM就能通过RTE来完成模式的Switch。
代码解析
动态配置代码
BswM模块生成的动态代码如下图所示。
我们下面针对一些常用的进行说明:
- BswM_PBcfg.c:顶层的结构体为BswM_Configurations_capcst,它包含了BswM_Config结构体,BswM_Config包含了仲裁配置结构体BSWM_CFG_MODEARBITRATION,模式控制结构体BSWM_CFG_MODECONTROL,这些结构体包含了大部分上文提到的BswM配置。
CONSTP2CONST(BswM_ConfigType,AUTOMATIC,BSWM_CONST) BswM_Configurations_capcst[BSWM_NO_OF_CONFIGSETS]= { &BswM_Config }; CONST(BswM_ConfigType, BSWM_CONST) BswM_Config = { BSWM_CFG_MODEARBITRATION, BSWM_CFG_MODECONTROL, BSWM_CFG_VERSION_INFO }; #define BSWM_CFG_MODECONTROL { \ BSWM_CFG_PBACTION, \ &BswM_Cfg_AL_cast[0] \ } static CONST(BswM_Cfg_ActionListType_tst, BSWM_CONST) BswM_Cfg_AL_cast [5] = { { /* ActionListName : BswM_AL_BswMPostRun */ BSWM_TRIGGER, 1, &BswM_Cfg_AL_BswM_AL_BswMPostRun_Items_cast[0], 0 /* Unique Number for ActionList */ } };
- BswM_Cfg_RL.c:根据最大的规则数,准备在运行阶段需要保留的规则状态信息变量。
- BswM_Cfg_MRP.c:针对Generic request, BswModeNotification, SwcModeNotification, and SwcModeRequest,Dcm Com Mode Request模式请求端口的RAM buffer。
/* RAM buffer to hold the mode value of Generic request, BswModeNotification, SwcModeNotification, and SwcModeRequest type MRPs */ VAR(BswM_Cfg_MRP_PC_GenReqType_tst, BSWM_VAR) BswM_Cfg_GenericReqModeInfo_ast[BSWM_NO_OF_GENREQ_TOTAL]= { { /* generated as default value for BswM_MRP_BswM_MDG */ FALSE, 0 }, { /* generated as default value for BswM_MRP_SwcModeRequest */ FALSE, 0 } };
- BswM_Cfg_ModeManagerReq.c:包含了BswM_Cfg_DfrdBswNotification_BswM_MRP_BswM_MDG_ECUM_STATE_STARTUP_ONE、BswM_Cfg_DfrdBswNotification_BswM_MRP_BswM_MDG_ECUM_STATE_STARTUP_TWO、BswM_Cfg_DfrdSwcReqst_BswM_MRP_SwcModeRequest模式切换函数实体。
/* Set of Deferred BswMSwcModeRequest Functions (Runnable Entities on Data Received Event )*/ /* These functions are used for all deferred mode request from SWC modules via RTE */ /*********************************************************** * Function name: void BswM_Cfg_DfrdSwcReqst_BswM_MRP_SwcModeRequest( void ) * Description: Runnable Entity on Data Received Event. * Parameter: None * Return value: None * Remarks: ***********************************************************/ FUNC(void, BswM_CODE) BswM_Cfg_DfrdSwcReqst_BswM_MRP_SwcModeRequest ( void ) { /* Local variables used */ uint8 bswM_Mode_u8 = 0; Std_ReturnType bswM_RteRead_ret_u8 = E_NOT_OK; Std_ReturnType bswM_RteReceive_ret_u8 = E_NOT_OK; /*Check if bswMRbModeRequestQueueSize is non zero value and reads the requested Mode to switch through Rte_Recieve Api */ bswM_RteRead_ret_u8 = Rte_Read_RP_BswMArbitration_0_BswM_MRP_SwcModeRequest_VDP_uint16( &bswM_Mode_u8); /* Check Rte read is successful */ if( (RTE_E_OK == bswM_RteRead_ret_u8)|| (RTE_E_OK == bswM_RteReceive_ret_u8) ) { /* Call the generic request function */ BswM_RequestMode( BSWM_CFG_USERID_BSWM_MRP_SWCMODEREQUEST, /* user */ bswM_Mode_u8 ); /* mode */ } }
- BswM_Cfg_LE.c:所有逻辑判断表达式LE的实体,完成逻辑判断。
/***************************************************************************************** * Function name : void BswM_Cfg_LE_BswM_LE_StartupTwo (boolean *validMode_pb,boolean *evalResult_pb) * Description : Evaluates the logical expression if the mode value is initialized and returns the result * Parameter : *validMode_pb: evaluates if all the modes are valid and assigns true to this address if valid, *evalResult_pb: result of the logical expression is copied to this address. * Return value : void * Remarks : *****************************************************************************************/ FUNC(void, BSWM_CODE) BswM_Cfg_LE_BswM_LE_StartupTwo ( P2VAR(boolean, AUTOMATIC, BSWM_APPL_DATA) isValidMode_pb, P2VAR(boolean, AUTOMATIC, BSWM_APPL_DATA) hasLogExpRes_pb ) { /* Initialize the pointers with default values */ *isValidMode_pb = FALSE; *hasLogExpRes_pb = FALSE; if(FALSE != BSWMMODEVALUE_BSWM_LE_STARTUPTWO) { /* All the mode condition values are valid, assign TRUE to pointer */ *isValidMode_pb = TRUE; if(FALSE != BSWMLOGEXP_BSWM_LE_STARTUPTWO) { /* Logical Expression evaluated to TRUE */ *hasLogExpRes_pb = TRUE; } } return; }
- BswM_Cfg_AC.c:所有涉及的动作实体,包括BswM_Cfg_AC_SchMSwitch_0_BswM_AI_BswMSwitchRun,BswM_Cfg_AC_SchMSwitch_1_BswM_AI_BswMSwitchStartupTwo以及用户自定义BswM_Cfg_AC_UserCallout_0_BswM_AI_GoDown。
/***************************************************************************************** * Function name : BswM_Cfg_AC_UserCallout_0_BswM_AI_GoDown * Description : UserCallout Function is invoked for Action. * Parameter : void * Return value : void * Remarks : *****************************************************************************************/ static FUNC(void, BSWM_CODE) BswM_Cfg_AC_UserCallout_0_BswM_AI_GoDown (void) { EcuM_GoDown(12); }
集成代码
下面介绍一下BswM涉及到的集成代码:
- BswM_Cfg_MemMap.h:将BswM涉及配置项(常量)的MemMap宏定义替换成上层Bsw的。
#if defined BSWM_START_SEC_VAR_CLEARED_8 /* 8 bit */ #define BSW_START_SEC_VAR_CLEARED_8 #include "Bsw_MemMap.h" #undef BSWM_START_SEC_VAR_CLEARED_8 #undef MEMMAP_ERROR
- BswM_MemMap.h:将BswM涉及代码的MemMap宏定义替换成上层Bsw的。
#if defined BswM_START_SEC_CODE /* For SWC memmap mapping, Integrator has to Map it with the configured value */ #undef BswM_START_SEC_CODE #elif defined BswM_STOP_SEC_CODE /* For SWC memmap mapping, Integrator has to Map it with the configured value */ #undef BswM_STOP_SEC_CODE #elif defined BSWM_START_SEC_CODE #define BSW_START_SEC_CODE #include "Bsw_MemMap.h" #undef BSWM_START_SEC_CODE #elif defined BSWM_STOP_SEC_CODE #define BSW_STOP_SEC_CODE #include "Bsw_MemMap.h" #undef BSWM_STOP_SEC_CODE #endif
- BswM_Cfg_SchM.h:BswM模块集成商需要实现的竞争机制,如下所示的模板是BswM为集成商提供的进入不可打断区域的宏定义,宏定义已经被静态代码使用,集成商需要具体实现。
#define SchM_Enter_BswM(BSWM_RESOURCE) #define SchM_Exit_BswM(BSWM_RESOURCE)
- BswM_Appl.c:函数在生成后的版本不兼容的情况下由BswM调用,集成商负责具体实现。
/* * This is a template file. It defines integration functions necessary to complete RTA-BSW. * The integrator must complete the templates before deploying software containing functions defined in this file. * Once templates have been completed, the integrator should delete the #error line. * Note: The integrator is responsible for updates made to this file. * * To remove the following error define the macro NOT_READY_FOR_TESTING_OR_DEPLOYMENT with a compiler option (e.g. -D NOT_READY_FOR_TESTING_OR_DEPLOYMENT) * The removal of the error only allows the user to proceed with the building phase */ #ifndef NOT_READY_FOR_TESTING_OR_DEPLOYMENT #error The content of this file is a template which provides empty stubs. The content of this file must be completed by the integrator accordingly to project specific requirements #else #warning The content of this file is a template which provides empty stubs. The content of this file must be completed by the integrator accordingly to project specific requirements #endif /* NOT_READY_FOR_TESTING_OR_DEPLOYMENT */ /***************************************************************************************** * Header Includes * *****************************************************************************************/ #include "Std_Types.h" #include "BswM.h" #include "BswM_Prv.h" /*********************************************************** * Function name: void BswM_Appl_IncompatibleGenerator( void ) * Description: Function called by BswM in case of version incompatibility in the post-build generate. * This an empty function. User will write the error handler code here. * Return value: None * Remarks: ***********************************************************/ #define BSWM_START_SEC_CODE #include "BswM_Cfg_MemMap.h" FUNC(void, BSWM_CODE) BswM_Appl_IncompatibleGenerator( void ) { /* Fill the error handling code to handle the version mis-match in the post-build structure */ return; } #define BSWM_STOP_SEC_CODE #include "BswM_Cfg_MemMap.h" /* ********************************************************************************************************************** */
静态代码
主要介绍常见的静态代码涉及API说明,具体详细完整的介绍读者可以参考《AUTOSAR_SWS_BSWModeManager.pdf》以及《RTA-BSWReferenceGuide.pdf》。
-
BswM_MainFunction:BswM_MainFunction执行对配置为BSWM_DEFERRED的请求端口涉及的规则进行评估仲裁。
-
BswM_Init:初始化BswM模块,它需要在启动操作系统以及SchM之前进行调用,它初始化所有BswM涉及的全局变量,初始化完成之后,BSW模式管理器将准备好仲裁传入模式请求。
-
BswM_Deinit:取消对BSW模式管理器的初始化。在BswM_Deinit调用后,即使发出任何模式请求或调用BswM主函数,BswM也不得进行模式处理。
-
BswM_CanSM_CurrentState:由CansM调用以指示其当前状态的函数。参数有所指示的状态对应的CAN通道以及CAN通道的当前状态。
-
BswM_ComM_CurrentMode:由ComM调用以指示ComM信道的当前通信模式的函数。参数有所指示状态对应的ComM通信信道以及ComM通信信道的当前状态。
-
BswM_Dcm_CommunicationMode_CurrentState:DCM调用的函数,通知BswM通信模式状态更改请求。涉及参数有诊断请求模式所对应的通信通道以及请求的诊断通信模式。
-
BswM_RequestMode:对请求模式的通用函数调用。此功能只能由没有特定模式请求接口的其他BSW模块使用。
下图为ETAS例程针对BswM相关代码流程。
十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。