电源管理

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

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

术语

本文档中使用了以下术语:

术语 说明
应用处理器 (AP) 系统芯片 (SoC) 的一部分。
板级支持处理器 (BSP) 产品正常运行所需的所有硬件特定代码。通常由 SoC 供应商和硬件制造商提供。它涵盖设备驱动程序、PMIC 序列代码和 SoC 启动等多项内容。
CarPowerManager (CPM) 公开一个 API 以供应用记录电源状态的更改。
CarPowerManagementService (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。第 1 级合作伙伴或原始设备制造商 (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 进入“开启”状态。在此状态下,AAOS 完全运行并与司机互动。
  • 关闭准备:当司机结束驾驶后,VHAL 会指示 AAOS 进入“关闭准备”状态。在此状态下,显示屏和音频处于关闭状态,AAOS 不会与司机互动。Android 系统仍在运行,可以自由更新应用和 Android 系统。如有更新,在更新完成后,Android 系统会进入“等待 VHAL 完成”状态。
  • 等待 VHAL 完成:此时,AAOS 会通知 VHAL 它已准备好关闭。VMCU 应将 SoC 置于“深度睡眠”状态,并断开应用处理器的电源。然后,AAOS 将进入“挂起到 RAM”状态,但不执行任何代码。

电源管理模块

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

模块名称 说明
CarPowerManager Java/C++ API。
CarPowerManagementService 协调电源状态转换。
CarPowerPolicyDaemon 与原生电源政策客户端进行通信。
车载 HAL 连接到 VMCU。
内核 挂起到 RAM/磁盘实现。

内核中实现了深度休眠/休眠功能(将 Android 挂起到 RAM/磁盘)。此功能以位于 /sys/power/state 的特殊文件形式提供给用户空间。AAOS 通过将 memdisk 写入此文件而挂起。

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

CPPD 管理电源政策,直至 CPMS 获得控制权为止。此外,它还会向原生监听器发送电源政策更改通知。

某些属性是在 VHAL 中定义的。为了与 VMCU 通信,CPMS 将读取和写入这些属性。应用可以使用在 CPM 中定义的接口来监控电源状态的更改。应用还能通过此接口注册电源政策监听器。此 API 可通过 Java 进行调用,并且带有 @hide/@System API 注解,这意味着它仅供特权应用使用。这些模块、应用和服务之间的关系如下所示:

电源组件参考图

图 2. 电源组件参考图

消息序列

上一节介绍了组成电源管理系统的模块。本节使用“进入深度睡眠”和“退出深度睡眠”示例来说明模块与应用之间的通信方式:

进入深度睡眠

只有 VMCU 可以启动深度睡眠。启动深度睡眠后,VMCU 会通过 VHAL 向 CPMS 发送通知。CPMS 通过使用由 CPM 提供的新状态 ID 调用 onStateChanged() 方法,将状态更改为“关闭准备”并向所有观察者(监控 CPMS 的应用和服务)广播此状态转换。

CPM 在应用/服务与 CPMS 之间进行协调。在 CPM 的 onStateChanged() 方法中,同步调用应用/服务的 onStateChanged() 方法。大多数应用和服务需要完成其准备后才能从该调用返回。特权服务可以在为 PRE_SHUTDOWN_PREPARESUSPEND_ENTERPOST_SUSPEND_ENTER 返回后,异步继续关闭准备。在此情况下,特权服务应在完成准备时对提供的 CompletablePowerStateChangeFuture 对象调用 complete()。请注意,SHUTDOWN_PREPARE 不允许异步准备。在向 VHAL 发送 DEEP_SLEEP_ENTRY 之前,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_ON 进入开启状态。系统完全正常运行。
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 系统正在启动,但尚在等待与 VHAL 建立通信,通信建立后才能进入开启状态。

CarPowerStateListener 取消注册

如需取消注册已注册到 CPM 的所有监听器对象,请调用 clearListener 方法:

powerManager.clearListener();

Android 实现上的系统集成

集成器负责以下几项:

  • 实现用于挂起 Android 的内核接口。
  • 实现用于执行以下操作的 VHAL 函数:
    • 将挂起或关闭的启动消息从汽车传播到 Android。
    • 将关闭就绪消息从 Android 发送到汽车。
    • 通过 Linux 内核接口启动 Android 的关闭或挂起操作。
  • 确保在设备处于挂起状态时停用所有唤醒源。
  • 确保足够快速地关闭应用,以免无限期推迟关闭进程。
  • 确保 BSP 根据电源政策启用/停用设备组件,以免阻止挂起/休眠

内核接口:/sys/power/state

当应用或服务将 mem(适用于挂起到 RAM)或 disk(适用于挂起到磁盘)写入位于 /sys/power/state 的文件时,AAOS 会将设备置于挂起模式。集成器必须提供一项功能来监控此文件并将 Linux 置于“挂起”电源状态。此功能可能会向 VMCU 发送 GPIO 以通知 VMCU,告知它设备已彻底关闭。集成器还负责消除 VHAL 向 VMCU 发送最终消息与系统进入挂起或关闭模式之间的任何竞态条件。

VHAL 的责任

VHAL 可提供车载网络与 Android 之间的接口。VHAL 用途如下:

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

当 CPMS 通知 VHAL 它已准备好关闭时,VHAL 将关闭就绪消息发送到 VMCU。一般情况下,该消息由 UART、SPI 和 USB 等芯片外设进行传输。发送该消息后,CPMS 便会调用内核命令将设备挂起或关闭。在执行此操作之前,VHAL 或 BSP 可能会对 GPIO 进行相应的切换,以指示 VMCU 可以安全地断开设备的电源。

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

名称 说明
AP_POWER_STATE_REPORT Android 通过此属性向 VMCU 报告状态转换(使用 VehicleApPowerStateReport 枚举值)。
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

值名称 说明 第二个值
WAIT_FOR_VHAL AP 正在启动,并且需要与 VHAL 建立通信。
DEEP_SLEEP_ENTRY AP 正在进入深度睡眠状态。VMCU 应在第二个值中指定的时间过后重新开启 AP。 必须设置
DEEP_SLEEP_EXIT AP 正在退出深度睡眠状态。
HIBERNATION_ENTRY AP 正在进入休眠状态。VMCU 应在第二个值中指定的时间过后重新开启 AP。 必须设置
HIBERNATION_EXIT AP 正在退出休眠状态。
SHUTDOWN_POSTPONE Android 尚未准备好关闭。VMCU 应等待第二个值中指定的时长后再关闭 AP。Android 可以通过发出额外的 SHUTDOWN_POSTPONE 报告来请求再次推迟关闭。 必须设置
SHUTDOWN_PREPARE Android 正在准备关闭。 必须设置
SHUTDOWN_START AP 已准备好关闭。VMCU 应在第二个值中指定的时间过后重新开启 AP。(VMCU 不需要支持定时开启功能。) 必须设置
SHUTDOWN_CANCELLED Android 正在停止关闭准备,并将进入 WAIT_FOR_VHAL。
ON Android 正在正常运行。

状态可以自主设置,也可以响应请求通过 VMCU 进行设置。

AP_POWER_STATE_REQ

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

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

第一个整数值表示 Android 要转换为的新状态。相应的语义在 VehicleApPowerStateReq.aidl 中进行了定义,如下所示:

值名称 说明
ON AP 应开始完全正常运行。
SHUTDOWN_PREPARE AP 应准备关闭。第二个值表示是否允许 AP 推迟关闭,以及 AP 是应断电还是进入深度睡眠。
CANCEL_SHUTDOWN AP 应停止准备关闭,并准备开启。
FINISHED 现在,AP 应已关闭或挂起。

VehicleApPowerStateShutdownParamVehicleApPowerStateShutdownParam.aidl 中定义。此枚举包含以下元素:

值名称 说明
CAN_SLEEP AP 可以进入深度睡眠而不是彻底关闭。允许推迟。
CAN_HIBERNATE AP 可以进入休眠而不是彻底关闭。允许推迟。
SHUTDOWN_ONLY AP 应关闭。允许推迟。不允许进入深度睡眠。
SLEEP_IMMEDIATELY AP 可进入深度睡眠,但必须立即睡眠或关闭。不允许推迟。
HIBERNATE_IMMEDIATELY AP 可进入“挂起到磁盘”状态,但必须立即休眠或关闭。不允许推迟。
SHUTDOWN_IMMEDIATELY AP 必须立即关闭。不允许推迟。不允许进入深度睡眠。

唤醒源

当设备处于挂起模式时,集成器必须停用相应的唤醒源。常见的唤醒源包括检测信号、调制解调器、Wi-Fi 和蓝牙。唯一有效的唤醒源必须是为了唤醒 SoC 而来自 VMCU 的中断。这假设 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 类和接口:

电源类图

图 5. 电源类图

对象关系

下图说明了哪些对象会引用其他对象。边缘表示源对象保持对目标对象的引用。例如,VehicleHAL 引用 PropertyHalService 对象。

对象引用图

图 6. 对象引用图