电源管理

为了支持特定于车辆的电源管理,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、联发科、Nvidia、高通、瑞萨电子和德州仪器等制造商提供。
挂起
也称为挂起到 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 的电源状态。状态机提供下图所示的状态

Car power state machine

图 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 的特殊文件公开给用户空间。通过将 memdisk 写入此文件来挂起 AAOS。

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

CPPD 在 CPMS 接管控制之前管理电源政策。它还会向原生监听器发送电源政策更改通知。

某些属性在 VHAL 中定义。为了与 VMCU 通信,CPMS 读取和写入这些属性。应用可以使用 CPM 中定义的接口来监控电源状态更改。此接口还使应用能够注册电源政策监听器。此 API 可以从 Java 调用,并使用 @hide / @System API 注释,这意味着它适用于特权应用。下图说明了这些模块、应用和服务之间的关系

Power components reference diagram

图 2. 电源组件参考图。

消息序列

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

进入深度睡眠

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

CPM 在应用/服务和 CPMS 之间进行协调。应用/服务的 onStateChanged() 方法在 CPM 的 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 还会调用其挂起方法,该方法会挂起内核。

下图说明了上述序列

Enter deep sleep

图 3. 进入深度睡眠。

CPM 提供的编程接口

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

  • 监控 AP 中的电源状态更改。
  • 应用电源政策。

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

  1. 要获取 CPM 实例,请调用 Car API。
  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 使用此属性,使用 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 中。

值名称 说明 第二个值
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 和蓝牙。唯一有效的唤醒源必须是来自 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 类和接口

Power class diagram

图 4. 电源类图。

对象关系

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

Object reference diagram

图 5. 对象引用图。