文章目录
>>>>>>>>>>返回专栏总目录《AUTOSAR从入门到精通专栏》 <<<<<<<<<<
关注文章末尾公众号或微信中搜索“AUTOSAR解忧杂货铺”,后台发送“资料”领取汽车电子入门资料,发送“加群”加入汽车电子交流群
一、简介
在汽车电子领域,EcuM(ECU State Manager)模块主要负责管理ECU的状态,这里的状态特指ECU的上下电状态,涵盖了STARTUP(启动)、OFF(关闭)、UP(运行)、SLEEP(休眠)等阶段。每个ECU状态都包含着丰富的内容。例如,当ECU进入STARTUP阶段时,需要对BswM(基础软件模式管理器)、OS(操作系统)、Rte(运行时环境)等模块进行初始化操作;而在UP阶段,则需要对唤醒事件进行验证。
由于汽车电子系统对ECU的上下电时序有着极为严格的要求,AUTOSAR(汽车开放系统架构)专门设计了EcuM模块,以将这个过程进行系列化管理,确保上下电过程规范、有序。
EcuM模块处于AUTOSAR的系统服务层。它一方面通过RTE与用户进行直接交互,另一方面在基础软件层面与BswM、ComM(通信管理器)以及各种驱动模块等进行交互,在整个汽车电子软件架构中发挥着重要的协调和管理作用。
二、ECU状态处理
在AUTOSAR架构中,ECU的状态管理由EcuM模块负责,其生命周期包含启动、运行、关闭等关键阶段。
-
启动(STARTUP)阶段作为系统初始化的核心环节,需完成底层驱动初始化、操作系统激活及基础软件调度表配置等操作。该过程分为两个阶段:
- 第一阶段OS阶段主要完成硬件抽象层初始化与中断配置
- 第二阶段OS阶段则通过调用
EcuM_StartupTwo
触发BSW调度器与模式管理器的初始化,确保系统进入可管理状态。当模式管理模块(BswM)就绪后,启动阶段结束,ECU正式进入运行(UP)状态。
-
运行阶段是ECU的主要工作周期,其状态迁移由集成工程师定义的状态机控制。在此期间,ECU可能经历多种状态(State)与模式(Mode)的转换。其中,State特指BSW模块内部的状态,如驱动初始化状态或通信模块状态,这些状态对上层应用透明;而Mode则关联整车或应用逻辑,例如EcuM定义的运行模式(如部分唤醒或完全激活),需通过RTE与应用层交互。运行阶段可能包含前置睡眠状态,此时系统会提前使能唤醒源,为进入低功耗模式做准备。
-
关闭(SHUTDOWN)阶段是启动的逆过程,当系统接收到关机请求时,EcuM将执行反初始化操作:首先保存关键数据至非易失性存储器,随后关闭BSW模块并调用OS_Shutdown终止操作系统。若在关闭过程中检测到有效唤醒事件,系统将立即终止关机流程并重启。该阶段的时序控制严格遵循AUTOSAR规范,确保数据完整性与系统可靠性。
可以将Ecu状态分为四个阶段:STARTUP、UP、SLEEP、SHUTDOWN。如下图所示,下面我们把各个阶段中的内容拆分开来看
2.1 STARTUP阶段
STARTUP阶段主要分为4个步骤:
- PowerOn : 上电或者Reset后,首先是从cstart.c这样的引导代码,引导ECU程序进入
core_mian()
接口; - StartPreOS :进入
EcuM_Init()
, 在这做如下表中的动作,最后才启动OS; - StartPostOS :启动OS之后会进入一个init task中,在该任务内须调用
EcuM_StartupTwo()
,StartPostOs 存在于该函数执行过程中。该函数主要执行两个操作,调用SchM_Init()
和调用BswM_Init()
。当 BswM 模块成功初始化后,后续的初始化任务由 BswM 模块完成。EcuM 的启动流程也就此结束。 - BswM启动:BswM启动之后,即STARTUP阶段完成,会在BswM中进行Rte_Start(),之后进入UP阶段。
步骤 | 函数/操作 | 说明 |
---|---|---|
1 | 执行 EcuM_AL_SetProgrammableInterrupts() | 主要负责关闭芯片的可编程中断,为初始化其他模块和启动操作系统做准备。若系统启动代码已将中断关闭,可通过配置参数省略该步骤,否则在函数中关闭中断。 |
2 | 执行EcuM_AL_DriverInitZero() | 初始化 Init List 0 容器里面的驱动。 |
3 | 执行EcuM_DeterminePbConfiguration() | 根据相关系统设计读取 Post - build 配置参数数据指针。 |
4 | 检查配置数据一致性 | 检查上一步得到的 Post - build 配置数据的有效性。 |
5 | 执行 EcuM_AL_DriverInitOne() | 初始化 Init List 1 容器里面的驱动。 |
6 | 获取上次复位原因 | 通过读取 MCU 的特殊复位原因寄存器,获取此次 ECU 复位的复位源,根据复位源进行不同处理。如复位原因是唤醒复位,需执行唤醒源确认等步骤;若为电源上电,需对 EcuM RAM 的一些关键变量进行初始化。 |
7 | 设置默认 Shutdown target | 系统关闭有三种情况(三种 ShutdownTarget),分别为 SLEEP(系统进入低功耗状态)、RESET(复位重新运行)和 OFF(完全断电)。 |
8 | 执行 EcuM_LoopDetection() | 这是一个 Callout 函数。 |
9 | 执行 StartOS() | 启动操作系统,入参为在 EcuM 模块配置的 OS 的 AppMode。该函数最终不会返回,因此 EcuM_Init()也不会返回。 |
Tip📌: StartPreOS 和StartPostOS之间以 OS 的启动为分界线,在 AUTOSAR OS 中 , 需 要 配 置 一 个 自 启 动 任 务 。 在 该 任 务 中 , 需 要 调 用EcuM_StartupTwo()
,StartPostOs
存在于该函数执行过程中。该函数主要执行两个操作,调用 SchM_Init()
和调用 BswM_Init()
。当 BswM 模块成功初始化后,后续的初始化任务由 BswM 模块完成。EcuM 的启动流程也就此结束。
在上述上电流程中,提到了Init Block。现在很多MCU对初始化外设的时序都有严格要求,所以EcuM 设计了几个驱动初始化列表以满足不同需求:
EcuMDriverInitListZero
在获取 Post-build 参数前调用,用于初始化基础模块和获取 PB 参数所需硬件驱动;EcuMDriverInitListOne
在获取 Post-build 参数后调用,用于初始化不依赖操作系统的多配置模块;EcuMDriverRestartList
在唤醒后用于重启驱动模块。这些列表确保了 ECU 的驱动程序按正确的顺序和条件进行初始化和重启,以支持系统的不同阶段和需求。
2.2 UP阶段
EcuM主要在EcuM_MainFunction
中干三件事:
- 唤醒源管理(唤醒源的识别和唤醒源的验证);
- Alarm clock的更新;
- 仲裁RUN 和POST_RUN的释放和请求;
2.2.1 唤醒源管理
分主动主动唤醒和被动唤醒源,如下图所示
2.2.2 Alarm clock
EcuM模块能够设定一个系统时间,该时间以秒为单位,从设备上电复位开始运行,基于GPT模块。用户通过EcuM_GetCurrentTime()
获取设备上电后的运行时长。即使在休眠状态,此时间也能正常运行,因为EcuM_MainFunction
会持续更新时间。因此,用户可以利用它作为定时唤醒源来唤醒系统。
Alarm clock功能允许为特定用户(如基础软件模块或软件组件)配置指定的时间。用户能够设置与自身相关的时钟时间。
2.2.3 Mode handing
RUN和POST_RUN是用户(SW-C)对EcuM模块的两种模式请求。
- RUN表示用户希望ECU处于正常运行状态
- POST_RUN表示用户需要在休眠或关闭前执行清理工作。
用户需通过EcuM模块接口单独请求或释放RUN和POST_RUN,且请求和释放必须成对进行。因EcuM内部无模式迁移状态机,仅负责处理请求并转发给BswM,由BswM管理状态机,并在模式迁移后通过EcuM和Rte通知SW-Cs。
EcuM模块整合所有SW-C的请求进行仲裁,向BswM模块发起模式请求,基本规则如下:
- 当至少有一个SW-C请求RUN时,EcuM向BswM请求系统进入RUN状态(通过
BswM_EcuM_Request-edState()
); - 当所有SW-C均释放RUN,但仍有至少一个SW-C请求POST_RUN时,EcuM向BswM请求进入POST_RUN状态(通过
BswM_EcuM_RequestedState()
); - 当所有SW-C的RUN和POST_RUN均释放时(通过
BswM_EcuM_RequestedState()
),EcuM向BswM告知当前状态并等待BswM发起系统关闭(EcuM_GoDown()
),根据shutdownTarget进入Sleep或Shutdown。 - 当BswM模式状态机迁移后,BswM通过 EcuM_SetMode() 设定EcuM状态,EcuM也通过
BswM_EcuM_CurrentState()
告知BswM当前状态。
通常,用户正常运行时请求RUN,应用停止运行且需后处理时,先请求POST_RUN再释放RUN。EcuM和BswM会根据系统状态切换到POST_RUN,并通知应用执行清理。清理完成后,应用调用EcuM接口释放POST_RUN,系统进入Sleep或Shutdown,由BswM决定进入时机。
2.3 SLEEP阶段
在UP阶段,当应用软件停止运行且总线满足休眠条件(例如CAN网络达到远程休眠状态)时,系统将进入SLEEP阶段。此过程由BswM触发,EcuM负责执行具体的休眠操作。
在进入低功耗模式之前,需要调用EcuM_SelectShutdownTarget()
函数将目标状态设置为SLEEP,并且要指定具体的休眠模式。不同的硬件芯片有不同的休眠特性:某些芯片在休眠时完全停止代码执行,而另一些芯片则可能进入低频模式继续执行代码。因此,需要根据硬件的实际情况选择调用EcuM_GoHalt()
或EcuM_GoSleep()
函数,以使MCU进入低功耗状态。
进入休眠状态的过程分为三个阶段:首先是预休眠阶段(GoSleep),接着是休眠阶段,最后是唤醒重启阶段。
2.3.1 GoSleep(预休眠)
如上图所示,在预休眠阶段,EcuM 会先调用BswM_EcuM_CurrentWakeup
来报告唤醒源的状态。接着,EcuM 调用EcuM_EnableWakeupSources()
接口以启用唤醒源,为未来的休眠做好准备。这个函数在集成代码中,用户需要判断每个输入参数中的 bit,并调用相应驱动的函数来启用每个唤醒源。之后,EcuM 会调用操作系统提供的接口函数GetResource()
来锁定调度功能,确保在未来的唤醒中断处理完成后,能够返回到当前进入休眠的任务中继续执行唤醒操作。
需要注意的是,SLEEP 阶段与 SHUTDOWN 阶段不同,因为在 SLEEP 阶段操作OS(系统)并未关闭。
2.3.2 Sleep(休眠)
Sleep分为两种模式,分别是Halt模式和Poll模式:
-
Poll模式休眠步骤
在Poll模式下,CPU继续以较低的主频执行代码。EcuM会循环执行以下两个动作:- 调用
EcuM_SleepActivity()
:这是一个集成代码,用户可以在其中实现低功耗状态下运行的任务。 - 调用
EcuM_CheckWakeup()
:同样是集成代码,用户需要在此根据输入参数遍历唤醒源,并调用相应驱动接口检查是否发生唤醒事件。若检测到唤醒事件,唤醒源应通过EcuM_SetWakeupEvent()
通知EcuM,后者在检查完成后触发唤醒重启。
- 调用
-
Halt模式休眠步骤
在Halt模式下,CPU停止执行所有代码。此时会禁用所有二类中断,为防止RAM内容被破坏,EcuM会调用EcuM_GenerateRamHash()
计算RAM的校验值。用户需在此函数中对关键内容进行检验并保存。之后,EcuM调用MCU驱动进入休眠模式,CPU处于停止状态,只有唤醒中断能将其重新激活。在退出Halt模式前,EcuM会调用EcuM_CheckRamHash()
进行校验,通过后才触发唤醒重启。
2.3.3 唤醒重启
在EcuM退出Poll或Halt状态后,会执行一系列的WakeupRestart步骤。具体来说,首先将MCU恢复到正常工作模式,然后获取当前的唤醒源,并且禁止那些已经被验证和挂起的唤醒源,以防止它们再次唤醒ECU,同时保留其他唤醒源以便后续使用。最后,调用EcuM_AL_DriverRestart()
接口来重新启动驱动列表,并解锁操作系统的调度器。
在驱动重新初始化的过程中,各个驱动需要检查自己是否是本次唤醒的触发源。如果是,则驱动会调用EcuM_SetWakeupEvent()
接口来通知EcuM。完成所有唤醒重启步骤后,系统将进入UP状态,此时仍有一些唤醒源需要进一步验证。
2.4 SHUTDOWN阶段
SHUTDOWN阶段主要分为4个步骤:
- BswM通知EcuM下电:在BswM准备好下电时会调用
EcuM_GoDown()
这个接口之后,EcuM开始下电流程。 - OffPreOs : EcuM会在
EcuM_MainFunction
进行下电处理。- 调用
EcuM_OnGoOffOne()
,这是一个集成代码,主要负责处理一些关闭前的特殊操作,需要根据芯片特性填充功能。 - 调用
BswM_Deinit()
,SchM_DeInit()
。 - 检查唤醒事件,如果在关闭过程中发生PENGING或确认的唤醒事件,则系统需要响应唤醒。所以若当前 Shutdown Target 为 OFF,EcuM 会将其更改为 RESET,即在执行完后续的关闭动作后将处理器复位,从而再次启动。若没有发生唤醒事件,则正常执行关闭流程。
- 执行
ShutdownOS()
,关闭操作系统。该函数会清理操作系统中的一些资源,最终调用ShutdownHook()
。
- 调用
- OffPostOs : 函数
ShutdownHook()
中会调用EcuM_Shutdown()
,OffPostOS 流程则是在EcuM_Shutdown()
中实现。OffPostOS 流程分为两个步骤:- 调用
EcuM_OnGoOffTwo()
。用户可以在其中调用不依赖于操作系统的模块的反初始化或清理工作。
根据前面设置的 Shutdown Target , 分别调用EcuM_AL_Reset()
、EcuM_AL_SwitchOff()
。用户需要在这两个函数中分别调用驱动来实现系统复位或关闭电源等工作,自此ECU完成Shutdown流程。
- 调用
三、设置 Bootloader 启动目标
在 ECU 需要进行 flash 操作时,诊断仪会与 Dcm 模块进行交互,设置 Bootloader 的重编程有效标志,然后触发 Reset 操作。在这个过程中,EcuM 模块提供了一个激活 Bootloader 的入口,以确保系统能够正确进入 Bootloader 模式进行重编程。
在 AUTOSAR 中实现这一流程,需要应用层调用 EcuM 模块的 EcuM_SelectBootTarget()
函数,以确定下次启动时的引导目标。该目标可以是应用、OEM Bootloader 或 System Bootloader。以下是具体流程:
- 诊断仪发送请求:诊断仪发送请求切换到编程会话。
- Dcm 模块请求复位:Dcm 模块通过 Rte 向应用请求复位,应用调用
EcuM_SelectBootTarget()
函数设置复位启动目标。 - Dcm 发送响应:Dcm 模块向诊断仪发送 0x78 响应,表示请求已被接受。
- 设置重编程标志:Dcm 调用集成代码的接口,用户在集成代码中设置 Bootloader 的重编程有效标志。
- 通知应用复位:Dcm 通知应用可以执行复位操作。
- 应用完成清理工作:应用完成复位前的清理工作后,请求 EcuM 复位。
- 触发复位操作:在 Shutdown 阶段,最后调用
EcuM_AL_Reset()
时,应当调用EcuM_GetBootTarget()
来获取当前引导目标。根据与 Bootloader 的交互协议设置相应标志,最后触发复位操作Mcu_PerformReset()
。
这一流程确保了系统能够正确进入 Bootloader 模式,完成重编程操作,并在完成后恢复到正常运行状态。
四、总结
EcuM通过与BswM、ComM、OS等模块协作,确保ECU在不同状态下的平滑切换。在启动阶段初始化各模块,在运行阶段管理唤醒源和模式请求,在休眠阶段协调低功耗模式的进入与退出,并在关闭阶段执行系统资源的清理与关闭操作。通过EcuM模块,AUTOSAR系统能够实现对ECU状态的精确控制和高效管理,满足汽车电子系统对可靠性和实时性的严格要求。