电源管理

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

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

术语

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

应用处理器 (AP)
系统芯片 (SoC) 的一部分。
板级支持包 (BSP)
包含硬件专用启动固件和设备驱动程序的软件层,这些固件和驱动程序使嵌入式操作系统能够在给定的硬件环境(主板)中正常运行。该软件层与嵌入式操作系统集成。
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 等制造商提供。
suspend
也称为“挂起到 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。
开启 Android 正在正常运行。

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

AP_POWER_STATE_REQ

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

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

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

值名称 说明
开启 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 类和接口:

电源类图

图 4. 电源类图。

对象关系

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

对象引用图

图 5. 对象引用图。