为了支持特定于车辆的电源管理,Android 提供了CarPowerManagementService
服务和CarPowerManager
接口。
状态转换由车辆主控制单元 (VMCU) 触发。为了与 VMCU 通信,集成商必须实现多个组件。集成商负责与车辆硬件抽象层(VHAL)和内核实现集成。集成商还负责禁用唤醒源并确保关闭不会无限期推迟。
术语
本文档中使用了这些术语:
suspend()
和shutdown()
的最终调用。系统设计
本节介绍 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
的特殊文件公开给用户空间。通过将mem
或disk
写入此文件来暂停 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_PREPARE
、 SUSPEND_ENTER
、 POST_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:
- 调用Car API获取CPM实例。
- 对步骤 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 现在将被关闭或暂停。 |
VehicleApPowerStateShutdownParam
在VehicleApPowerStateShutdownParam.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 的服务,例如VehicleHal 和HAlClient 。 | 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.对象参考图。