电源管理

为了支持特定于车辆的电源管理,Android 提供了CarPowerManagementService服务和CarPowerManager接口。

状态转换由车辆主控制单元 (VMCU) 触发。为了与 VMCU 通信,集成商必须实现多个组件。集成商负责与车辆硬件抽象层(VHAL)和内核实现集成。集成商还负责禁用唤醒源并确保关闭不会无限期推迟。

术语

本文档中使用了这些术语:

应用处理器 (AP)
片上系统 (SoC)的一部分。
板级支持包 (BSP)
软件层,包含特定于硬件的启动固件和设备驱动程序,允许嵌入式操作系统在给定的硬件环境(主板)中运行,并与嵌入式操作系统集成。
汽车电源管理器 (CPM)
公开 API 供应用程序注册电源状态更改。
汽车电源管理服务 (CPMS)
实现汽车电源状态机,与 VHAL 接口,并执行对suspend()shutdown()的最终调用。
CarPowerPolicyDaemon(CPPD)
公开本机进程的 AIDL 接口以注册电源策略侦听器。
通用输入或输出 (GPIO)
通用数字信号引脚。
硬件抽象层(HAL)
所有其他更高级别的模块必须与之交互才能访问硬件功能的软件层。
休眠
也称为挂起至磁盘(S2D/S4)。 SoC 被置于 S4 电源模式(休眠),RAM 内容被写入非易失性介质(例如闪存或磁盘),并且整个系统断电。
媒体处理器 (MP)
请参阅片上系统 (SoC)
电源管理集成电路(PMIC)
用于管理主机系统电源需求的芯片。
片上系统 (SoC)
运行 AAOS 的主处理器,通常由 Intel、MediaTek、Nvidia、Qualcomm、Renesas 和 Texas Instruments 等制造商提供。
暂停
也称为挂起至 RAM (S2R 或 STR)。 SoC 被置于 S3 电源模式,CPU 断电,而 RAM 保持通电状态。
车辆 HAL (VHAL)
Android API 用于与车辆网络交互。一级合作伙伴或 OEM 负责编写此模块。车辆网络可以使用任何物理层(例如CAN、LIN、MOST和以太网)。 VHAL 对该车辆网络进行抽象,使 AAOS 能够与车辆交互。
车辆接口处理器 (VIP)
请参阅车辆 MCU。
车辆主控制单元(VMCU)
提供车辆网络和 SoC 之间接口的微控制器。 SoC 通过 USB、UART、SPI 和 GPIO 信号与 VMCU 通信。

系统设计

本节介绍 AAOS 如何表示应用处理器的电源状态以及哪些模块实现电源管理系统。本材料还描述了这些模块如何协同工作以及状态转换通常如何发生。

汽车电源状态机

AAOS 使用状态机来表示 AP 的电源状态。状态机提供如下所示的状态:

汽车电源状态机

图 1.汽车电源状态机。

最常见的转换以蓝色突出显示。这些是状态和常见的转换:

  • 挂起至 RAM。车辆和 SoC 已关闭。没有代码正在执行。 SoC RAM 保持供电。
  • 等待VHAL。当驾驶员与车辆交互时(例如打开车门),VMCU 会向 SoC 供电。 AAOS 从挂起到 RAM 恢复并进入等待 VHAL,等待与 VHAL 协调。
  • 在。 VHAL 通知 AAOS 进入 On 状态。在此状态下,AAOS 完全运行并与驱动程序交互。
  • 关机准备。当驾驶员完成驾驶后,VHAL 通知 AAOS 进入关机准备状态。在此状态下,显示和音频关闭,并且 AAOS 不与驾驶员交互。 Android系统仍在运行,可以免费更新应用程序和Android系统。当更新(如果有)完成时,Android 系统会进入“等待 VHAL 完成”。
  • 等待 VHAL 完成。此时,AAOS 通知 VHAL 它已准备好关闭。 VMCU 预计会将 SoC 置于深度睡眠状态并切断应用处理​​器的电源。然后 AAOS 处于挂起至 RAM 状态,但没有执行任何代码。

电源管理模块

电源管理系统由以下模块组成:

模块名称描述
汽车电源管理器Java 或 C++ API。
汽车电源管理服务协调电源状态转换。
汽车电源政策守护进程与本机电源策略客户端通信。
车辆HAL VMCU 的接口。
核心挂起到RAM或磁盘执行。

深度睡眠/休眠功能(将 Android 挂起至 RAM/磁盘)是在内核中实现的。此功能作为位于/sys/power/state的特殊文件公开给用户空间。通过将memdisk写入此文件来暂停 AAOS。

CPMS 与其他服务和 HAL 协调电源状态。 CPMS 实现上述状态机,并在发生电源状态转换时向每个观察者发送通知。该服务还使用 VHAL 向硬件发送消息。

CPPD 管理电源策略,直到 CPMS 取得控制权。它还向本机侦听器发送电源策略更改通知。

一些属性在 VHAL 中定义。为了与 VMCU 通信,CPMS 读取和写入这些属性。应用程序可以使用CPM中定义的接口来监视电源状态变化。此接口还允许应用程序注册电源策略侦听器。该API可以从Java中调用,并使用@hide / @System API进行注释,这意味着它适用于特权应用程序。这些模块、应用程序和服务之间的关系如下所示:

功率元件参考图

图 2.电源组件参考图。

消息顺序

上一节描述了构成电源管理系统的模块。本节使用进入深度睡眠退出深度睡眠示例来解释模块和应用程序如何通信:

进入深度睡眠

只有 VMCU 可以启动深度睡眠。一旦启动深度睡眠,VMCU 就会通过 VHAL 向 CPMS 发送通知。 CPMS 将状态更改为 SHUTDOWN PREPARE,并通过使用 CPM 提供的新状态 ID 调用onStateChanged()方法,向所有观察者(监视 CPMS 的应用程序和服务)广播此状态转换。

CPM 在应用程序/服务和 CPMS 之间进行协调。应用程序/服务的onStateChanged()方法在 CPM 的onStateChanged()方法中同步调用。大多数应用程序和服务都需要在从此调用返回之前完成准备工作。返回PRE_SHUTDOWN_PREPARESUSPEND_ENTERPOST_SUSPEND_ENTER后,特权服务可以继续异步准备。在这种情况下,特权服务应该在完成其准备时对所提供的CompletablePowerStateChangeFuture对象调用complete()。请注意, SHUTDOWN_PREPARE不允许异步准备。在将DEEP_SLEEP_ENTRY发送到 VHAL 之前,CPMS 定期向 VHAL 发送关闭推迟请求。

当所有 CPM 对象完成关闭准备后,CPMS 向 VHAL 发送AP_POWER_STATE_REPORT ,然后 VHAL 通知 VMCU AP 已准备好挂起。 CPMS 还调用其挂起方法,该方法挂起内核。

上述顺序如下图所示:

进入深度睡眠

图 3.进入深度睡眠。

CPM提供的编程接口

本节介绍 CPM 为系统应用和服务提供的 Java API。该 API 使系统软件能够:

  • 监视 AP 中的电源状态变化。
  • 应用电源策略。

使用以下步骤调用 CPM 提供的 API:

  1. 调用Car API获取CPM实例。
  2. 对步骤 1 中创建的对象调用适当的方法。

创建 CarPowerManager 对象

要创建 CPM 对象,请调用 Car 对象的getCarManager()方法。该方法是用于创建 CPM 对象的外观。指定android.car.Car.POWER_SERVICE作为参数来创建 CPM 对象。

Car car = Car.createCar(this);
CarPowerManager powerManager =
  (CarPowerManager) car.getCarManager(android.car.Car.POWER_SERVICE);

CarPowerStateListener 和注册

系统应用和服务可以通过实现CarPowerManager.CarPowerStateListener来接收电源状态更改通知。该接口定义了一个方法onStateChanged() ,它是 CPMS 电源状态更改时调用的回调函数。以下示例定义了一个实现该接口的新匿名类:

private final CarPowerManager.CarPowerStateListener powerListener =
  new CarPowerManager.CarPowerStateListener () {
    @Override
     public void onStateChanged(int state) {
       Log.i(TAG, "onStateChanged() state = " + state);
     }
};

要指示此侦听器对象监视电源状态转换,请创建一个新的执行线程并将侦听器和此线程注册到 CPM 对象:

executor = new ThreadPerTaskExecutor();
powerManager.setListener(powerListener, executor);

当电源状态更改时,将调用侦听器对象的onStateChanged()方法,并使用一个值来表示新的电源状态。实际值和电源状态之间的关联在CarPowerManager中定义,如下表所示:

姓名描述
状态开启进入开机状态。该系统已全面投入运行。
STATE_SHUTDOWN_CANCELLED关闭被取消,电源状态返回到正常状态。
STATE_SHUTDOWN_ENTER应用程序预计会清理并准备关闭。
STATE_POST_SHUTDOWN_ENTER关闭准备工作已完成,VMCU 已准备好关闭。进入关机状态。
STATE_PRE_SHUTDOWN_PREPARE已请求关闭过程,但 CPMS 尚未启动该过程。显示和音频仍然打开
STATE_SHUTDOWN_PREPARE在此期间可能会运行车库模式。
STATE_SUSPEND_ENTER应用程序预计会进行清理并准备好挂起至 RAM。
STATE_POST_SUSPEND_ENTER挂起至 RAM 的准备工作已完成,VMCU 已准备好挂起至 RAM。进入挂起状态。
STATE_SUSPEND_EXIT从挂起中唤醒或从取消的挂起中恢复。
STATE_HIBERNATION_ENTER应用程序预计会进行清理并准备好休眠。
STATE_POST_HIBERNATION_ENTER休眠准备工作已完成,VMCU 已准备好休眠 进入休眠状态。
STATE_HIBERNATION_EXIT从休眠状态中唤醒或从取消的休眠状态中恢复。
STATE_WAIT_FOR_VHAL系统正在启动,但在进入 ON 状态之前等待与 VHAL 建立通信。

CarPowerStateListener 注销

要取消注册所有注册到 CPM 的侦听器对象,请调用clearListener方法:

powerManager.clearListener();

Android 实现上的系统集成

集成商负责以下事项:

  • 实现暂停 Android 的内核接口。
  • 实施 VHAL 功能以:
    • 将暂停或关闭的启动从汽车传播到 Android。
    • 将关闭就绪消息从 Android 发送到汽车。
    • 通过 Linux 内核接口启动 Android 的关闭或挂起。
  • 确保设备处于挂起状态时禁用所有唤醒源。
  • 确保应用程序关闭得足够快,以免无限期推迟关闭过程。
  • 确保 BSP 根据电源策略打开(或关闭)设备组件,以免阻止挂起或休眠

内核接口:/sys/power/state

当应用程序或服务将用于挂起到 RAM 的mem或用于挂起到磁盘的disk写入位于/sys/power/state文件中时,AAOS 会将设备置于挂起模式。集成商必须提供一个功能来监视该文件并将Linux 置于挂起电源状态。该函数可以向VMCU发送GPIO以通知VMCU设备已完全关闭。集成商还负责消除 VHAL 向 VMCU 发送最终消息与系统进入挂起或关闭模式之间的任何竞争条件。

VHAL责任

VHAL 提供车辆网络和 Android 之间的接口。虚拟哈尔:

  • 将暂停或关闭的启动从汽车传播到 Android。
  • 将关闭就绪消息从 Android 发送到汽车。
  • 通过 Linux 内核接口启动 Android 的关闭或挂起。

当 CPMS 通知 VHAL 准备关闭时,VHAL 向 VMCU 发送关闭准备消息。通常,片上外设(例如 UART、SPI 和 USB)传输消息。发送消息后,CPMS 调用内核命令来挂起或关闭设备。在此之前,VHAL 或 BSP 可能会切换 GPIO 以指示 VMCU 可以安全地断开设备电源。

VHAL 必须支持以下属性,这些属性通过 VHAL 控制电源管理:

姓名描述
AP_POWER_STATE_REPORT Android 使用 VehicleApPowerStateReport 枚举值通过此属性向 VMCU 报告状态转换。
AP_POWER_STATE_REQ VMCU 使用此属性指示 Android 使用 VehicleApPowerStateReq 枚举值转换到不同的电源状态。

AP_POWER_STATE_REPORT

使用此属性报告 Android 当前的电源管理状态。该属性包含两个整数:

  • int32Values[0] :当前状态的 VehicleApPowerStateReport 枚举。
  • int32Values[1] :推迟或休眠或关闭的时间(以毫秒为单位)。该值的含义取决于第一个值。

第一个值可以采用以下值之一。 VehicleApPowerStateReport.aidl包含更具体的描述,这些描述存储在hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle中。

值名称描述第二个值
等待_FOR_VHAL AP 正在启动,需要与 VHAL 建立通信。
深度睡眠进入AP正在进入深度睡眠状态。 VMCU 应在第二个值中指定的时间后重新打开 AP。必须设置
深度睡眠退出AP 正在退出深度睡眠状态。
HIBERNATION_ENTRY AP 正在进入休眠状态。 VMCU 应在第二个值中指定的时间后重新打开 AP。必须设置
休眠_退出AP 正在退出休眠状态。
SHUTDOWN_POSTPONE Android 尚未准备好关闭。 VMCU 应在关闭 AP 之前等待第二个值中指定的时间。 Android 可能会通过发出额外的 SHUTDOWN_POSTPONE 报告来请求额外的推迟。必须设置
关闭_准备Android 正准备关闭。必须设置
关闭_启动AP 已准备好关闭。 VMCU 应在第二个值中指定的时间后重新打开 AP。 (VMCU 不需要支持定时开启功能。)必须设置
关闭_取消Android 不再准备关闭,并将继续进行 WAIT_FOR_VHAL。
安卓运行正常。

状态可以自主设置或响应通过 VMCU 的请求。

AP_POWER_STATE_REQ

该属性由 VMCU 发送,用于将 Android 转换到不同的电源状态,并包含两个整数:

  • int32Values[0]VehicleApPowerStateReq枚举值,表示要转换到的新状态。
  • int32Values[1]VehicleApPowerStateShutdownParam枚举值。该值仅针对SHUTDOWN_PREPARE消息发送,并将其包含的选项传输到 Android。

第一个整数值表示 Android 要转换到的新状态。语义在VehicleApPowerStateReq.aidl中定义并提供如下:

值名称描述
AP 应开始全面运行。
关闭_准备AP 应准备关闭。第二个值指示是否允许 AP 推迟关闭以及 AP 是否应该关闭电源或进入深度睡眠。
取消_关闭AP 应停止准备关闭并准备开启。
完成的AP 现在将被关闭或暂停。

VehicleApPowerStateShutdownParamVehicleApPowerStateShutdownParam.aidl中定义。该枚举具有以下元素:

值名称描述
CAN_SLEEP AP可以进入深度睡眠而不是完全关闭。允许推迟。
可以休眠AP 可以进入休眠状态而不是完全关闭。允许推迟。
仅关闭AP 应关闭。允许推迟。深度睡眠是不允许的。
立即睡眠AP 可以进入深度睡眠,但必须立即睡眠或关闭。不允许推迟。
HIBERNATE_IMMEDIATELY AP 可以进入磁盘挂起状态,但必须立即休眠或关闭。不允许推迟。
立即关闭AP 必须立即关闭。不允许推迟。深度睡眠是不允许的。

唤醒源

当器件处于挂起模式时,集成器必须禁用适当的唤醒源。常见的唤醒源包括心跳、调制解调器、Wi-Fi 和蓝牙。唯一有效的唤醒源必须是来自 VMCU 的中断才能唤醒 SoC。这假设 VMCU 可以侦听调制解调器的远程唤醒事件(例如远程发动机启动)。如果将此功能推送到 AP,则必须添加另一个唤醒源来为调制解调器提供服务。

应用

OEM 必须小心编写应用程序,以便能够快速关闭,而不是无限期地推迟该过程。

附录

源代码树中的目录

内容目录
CarPowerManager相关代码。 packages/services/Car/car-lib/src/android/car/hardware/power
CarPowerManagementService等。 packages/services/Car/service/src/com/android/car/power
处理 VHAL 的服务,例如VehicleHalHAlClient packages/services/Car/service/src/com/android/car/hal
VHAL 接口和属性定义。 hardware/interfaces/automotive/vehicle/aidl/android/hardware/automotive/vehicle/
示例应用程序提供有关CarPowerManager的一些想法packages/services/Car/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink

类图

该类图显示了电源管理系统中的 Java 类和接口:

功率等级图

图 4.功率等级图。

对象关系

图 5 说明了哪些对象引用了其他对象。边缘意味着源对象持有对目标对象的引用。例如,VehicleHAL 具有对 PropertyHalService 对象的引用。

对象参考图

图 5.对象参考图。