为了支持车辆专用的电源管理,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 通过将 mem
或 disk
写入此文件而挂起。
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_PREPARE
、SUSPEND_ENTER
和 POST_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:
- 调用 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_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 应已关闭或挂起。 |
VehicleApPowerStateShutdownParam
在 VehicleApPowerStateShutdownParam.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 的服务,如 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 类和接口:
图 5. 电源类图
对象关系
下图说明了哪些对象会引用其他对象。边缘表示源对象保持对目标对象的引用。例如,VehicleHAL 引用 PropertyHalService 对象。
图 6. 对象引用图