接上一篇:从手写代码到AUTOSAR工具链 - RTE入门篇
EcuM是AUTOSAR中最基本也是最重要的BSW模块之一,其使用方法相对简单,但弄清楚其中的运行机制并不容易。本文依旧从传统的手工编程入手,着重突出EcuM的应用方法,对模块的内部机理仅做简单介绍,感兴趣的读者可参考相应AUTOSAR规范。
EcuM用于ECU状态管理,其主要功用包括:
- 初始化(Init)和反向初始化(Deinit)OS、SchM、BswM和一些基础软件驱动模块。
- 如果需要,配置ECU进入SLEEP和SHUTDOWN状态。
- 管理ECU的所有唤醒事件。
图2-1绘制了EcuM模块的“阶段(Phases)”,包括STARTUP、UP、SHUTDOWN和SLEEP。
图2-1: EcuM阶段
STARTUP阶段的目的是初始化基础软件模块直到通用模式管理机制开始运行。
在调用EcuM_Init函数后,EcuM接管ECU启动程序的控制;随着StartOS的调用,EcuM临时交出控制权。集成者可通过实现“自动启动和EcuM_StartupTwo作为第1个调用行为”的OS任务使EcuM重新获得控制权。
在UP刚开始时,BSW调度器已经启动,BswM_Init已经被调用。但内存管理没有初始化,没有通信栈,RTE没有启动,SWCs没有启动。进程通过相应的运行实体(Runnables)以特定模式(Startup后下一个配置项)启动,如:BSW主函数,然后以模式改变的任意组合启动BswM执行行为,同时触发或禁用相应的运行实体。
从EcuM模块的角度,ECU已经“起来”。BswM模块启动模式仲裁和更多BSW初始化,通过执行BswM行为列表或驱动模式相关调度启动RTE和SWC。
初始化BSW模块和启动SWC可以任意次序进行,直到ECU实现全功能;最后,模式切换停止SWC并反向初始化BSW,UP阶段结束,ECU到达可以休眠或下电的状态。
SHUTDOWN阶段处理基础软件模块的关闭,最终导致设备关闭或复位。
ECU在SLEEP阶段处于低功耗状态。通常来说,程序代码不再执行,但仍然有供电,ECU可以被唤醒。EcuM模块提供可配置的硬件休眠模式集,通常在功耗和重启时间之间做出权衡。
EcuM模块根据有意或无意的唤醒事件唤醒ECU,由于无意的唤醒事件应被忽略,EcuM模块提供了一个验证唤醒事件的协议。该协议规定了在处理唤醒源驱动和EcuM之间如何协作处理。
ECU当其下电时进入OFF状态,此时它只能被集成电源控制的唤醒源唤醒。在任何情况下ECU必须能被启动(如:复位事件)。
EcuM模块在大多数情况下仅负责初始化和反向初始化。包括一些基础软件驱动模块的初始化、关闭和唤醒时的重新初始化;OS初始化和关闭。
在OS初始化之后,控制传递给BswM之前,EcuM模块仍需承担附加的初始化步骤;在OS关闭之前,BswM立即将执行控制权交还给EcuM模块。
以ETAS公司的ISOLAR-AB工具为例说明EcuM模块的设计步骤。
在ISOLAR-AB中创建EcuM_EcucValues.arxml文件并将其拷贝到相应路径下。
在ISOLAR-B中创建并配置EcuM模块。
我们继续以应用在重卡主驾座椅上的“ECAS控制器”为例,说明EcuM的实现过程。该控制器的核心功能是“将座椅高度始终保持在设定位置上”,通过控制进气阀和排气阀的开闭调节空气弹簧的充气量,从而实现加载在座椅的重量发生变化时(不坐人或坐不同重量的人)其高度始终不变。表3-1为与之相关的主要部件及其功用。
表3-1: 座椅ECAS控制器相关主要部件及其功用
序号 |
部件名称 |
功用 |
1 |
高度传感器 |
实时采集座椅当前高度 |
2 |
进气阀和排气阀 |
(1)进气阀打开,排气阀关闭:空气弹簧充气,座椅高度上升 (2)进气阀关闭,排气阀打开:空气弹簧放气,座椅高度下降 (3)进气阀和排气阀都关闭:空气弹簧无动作,座椅高度不变 (4)进气阀和排气阀都打开:错误状态 |
从前文的描述可以看出,EcuM主要完成车载嵌入式软件“初始化”和“关闭”阶段,即“一头一尾”的工作,中间部分由BswM完成。“座椅ECAS控制器”由于功能比较简单,并没有用到OS,故只需考虑其初始化阶段的程序段即可,表3-2列出了通常情况下应在EcuM初始化的功能块,主要包括单片机外设驱动和外围芯片驱动的初始化。
表3-2: EcuM初始化模块
序号 |
分类 |
函数 |
功用 |
1 |
MCAL |
CGC_Init |
Clock初始化 |
2 |
PORT_Init |
Port初始化 |
|
3 |
ADC_Init |
ADC初始化 |
|
4 |
TAU0_Init |
GPT初始化 |
|
5 |
WDT_Init |
Wdg初始化 |
|
6 |
OS |
Tim_Init |
时间触发时标初始化 |
7 |
CDD |
BspKey_Init |
按键处理初始化 |
8 |
In_Init |
输入模块初始化 |
|
9 |
Out_Init |
输出模块初始化 |
手写代码实现程序初始化的部分,还是比较简单的,图4-1为代码截图。
图4-1: EcuM手写代码实现
本章介绍在ISOLAR-AB中创建和配置“座椅ECAS控制器”EcuM模块的步骤。
首先需要在ISOLAR-B中创建EcuM模块及其ARXML文件,再对其进行“整体配置”,这是后续一系列配置操作的基础。
按照图5-1和图5-2所示的步骤创建EcuM模块。
图5-1: EcuM模块创建启动
图5-2: EcuM模块创建操作
按照图5-3所示进入EcuM整体配置界面,可以在这里根据需要配置EcuM主函数调用周期、包含头文件、运行核等参数。
图5-3: EcuM整体配置界面
该箱包含EcuM的通用配置参数,图5-4为其配置启动界面。
图5-4: EcuM通用配置
这里面比较重要的配置箱为:EcuM驱动初始化列表〇(EcuMDriverInitListZero)和EcuM驱动初始化列表一(EcuMDriverInitListOne),用于实现表3-2中的初始化函数,AUTOSAR规范还专门对两者的初始化行为给出了建议,如表5-1所列。
表5-1: EcuM初始化列表
序号 |
配置项 |
初始化行为 |
1 |
EcuMDriverInitListZero |
Det |
Dem |
||
... |
||
2 |
EcuMDriverInitListOne |
Mcu |
Port |
||
Dio |
||
Gpt |
||
Wdg |
||
Adc |
||
Icu |
||
Pwm |
||
Ocu |
||
... |
由于座椅ECAS控制器没有Det、Dem等模块,这里将初始化行为均配置在“EcuMDriverInitListOne”中,表5-2为“Port初始化”的参数配置,其余模块的初始化与之类似。
表5-2: Port初始化参数配置
序号 |
配置项 |
配置值 |
说明 |
1 |
ShortName |
PORT |
配置箱名称 |
2 |
EcuMModuleID |
PORT |
初始化模块的短名称 |
3 |
EcuMModuleParameter |
VOID |
函数原型和输入参数定义 |
4 |
EcuMModuleService |
Init |
模块初始化方式,按照这里配置的初始化函数调用方式为PORT_Init() |
5 |
EcuMRbDriverInitCoreId |
- |
指定驱动初始化被哪个核调用 |
6 |
EcuMRbMonitoringCapable |
- |
指定模块不生成监控服务 |
7 |
EcuMRbSequenceID |
- |
生成的功能桩基于模块配置的顺序 |
8 |
EcuMModuleRef |
- |
模块示例的外部引用,不配置EcuMModuleID时有效 |
该箱包含EcuM灵活状态机的配置参数,图5-5为其配置启动界面,在其中可按需配置EcuM复位模式、下电原因等参数。
图5-5: EcuM灵活状态机配置
在完成BSW生成操作后,由图5-6的代码截图可以看出,工具链生成的代码与手工编程的代码类似。
图5-6: EcuM模块工具链生成代码截图
不知道大家是否还记得上期《从手写代码到AUTOSAR工具链_RTE入门篇》中没有说到的算法模块初始化函数Controller_initialize的调用,通过本文讲述的EcuM方式实现当然是可以的,不过对于应用层初始化的调用,更常用的做法是在“ECUM_STATE_RUN”中实现,这就涉及到AUTOSAR的另一个模块 - BswM的使用。
在AUTOSAR规范中,BswM是一个重要、有用、又好玩的模块,我研究了3次才想到了一个将其功用描述清楚的办法,我们下期讨论,敬请期待。