上下文中心运行时环境 (CHRE)

智能手机包含许多处理器,每个处理器都针对执行不同的任务进行了优化。然而,Android 只在一个处理器上运行:应用处理器 (AP)。该 AP 经过优化,可为游戏等屏幕开启用例提供出色的性能,但它太耗电,无法支持始终需要频繁、短时间处理的功能,即使屏幕关闭也是如此。较小的处理器能够更有效地处理这些工作负载,完成任务而不会显着影响电池寿命。然而,这些低功耗处理器中的软件环境更加有限,并且变化很大,使得跨平台开发变得困难。

Context Hub 运行时环境 (CHRE) 为在低功耗处理器上运行应用程序提供了一个通用平台,具有简单、标准化、嵌入式友好的 API。 CHRE 使设备 OEM 及其可信赖的合作伙伴能够轻松地从 AP 卸载处理,节省电池并改善用户体验的各个领域,并启用一类始终在线、上下文感知的功能,尤其是那些涉及机器应用的功能学习环境感知。

关键概念

CHRE 是一种软件环境,称为nanoapps的小型原生应用程序在低功耗处理器上执行并通过通用 CHRE API 与底层系统交互。为了加快 CHRE API 的正确实施,在 AOSP 中包含了 CHRE 的跨平台参考实施。参考实现包括通用代码和通过一系列平台抽象层 (PAL) 对底层硬件和软件的抽象。 Nanoapps 几乎总是与运行在 Android 中的一个或多个客户端应用程序相关联,这些客户端应用程序通过受限访问的ContextHubManager系统 API 与 CHRE 和 nanoapps 交互。

在高层次上,可以在 CHRE 的架构和整个 Android 之间绘制相似之处。但是,有一些重要的区别:

  • CHRE 仅支持运行以本机代码(C 或 C++)开发的 nanoapps;不支持 Java。
  • 由于资源限制和安全限制,CHRE 不开放供任意第三方 Android 应用使用。只有系统信任的应用程序才能访问它。

CHRE 的概念和传感器集线器之间还有一个重要的区别。虽然通常使用相同的硬件来实现传感器集线器和 CHRE,但 CHRE 本身并不提供Android Sensors HAL所需的传感器功能。 CHRE 与 Context Hub HAL 相关联,它充当特定于设备的传感器框架的客户端,以在不涉及 AP 的情况下接收传感器数据。

CHRE 框架架构

图 1. CHRE 框架架构

上下文中心 HAL

Context Hub 硬件抽象层 (HAL) 是 Android 框架和设备的 CHRE 实现之间的接口,定义在hardware/interfaces/contexthub中。上下文中心 HAL 定义了 API,Android 框架通过这些 API 发现可用的上下文中心及其 nanoapps,通过消息传递与这些 nanoapps 交互,并允许加载和卸载 nanoapps。与 CHRE 的参考实现一起使用的 Context Hub HAL 的参考实现位于system/chre/host

如果本文档与 HAL 定义发生冲突,则以 HAL 定义为准。

初始化

当 Android 启动时, ContextHubService会调用getHubs() HAL 函数来确定设备上是否有可用的上下文中心。这是一个阻塞的一次性调用,因此它必须快速完成以避免延迟启动,并且它必须返回准确的结果,因为之后无法引入新的上下文集线器。

加载和卸载 nanoapps

上下文中心可以包含一组包含在设备映像中并在 CHRE 启动时加载的 nanoapps。这些被称为预加载的 nanoapps,应该包含在对queryApps()的第一个可能的响应中。

Context Hub HAL 还支持在运行时通过loadNanoApp()unloadNanoApp()函数动态加载和卸载 nanoapp。 Nanoapps 以特定于设备的 CHRE 硬件和软件实现的二进制格式提供给 HAL。

如果加载 nanoapp 的实现涉及将其写入非易失性内存,例如连接到运行 CHRE 的处理器的闪存,则 CHRE 实现必须始终在这些动态 nanoapp 处于禁用状态时启动。这意味着在通过 HAL 接收到enableNanoapp()请求之前,不会执行 nanoapp 的任何代码。预加载的 nanoapps 可以在启用状态下初始化。

上下文中心重新启动

虽然 CHRE 预计不会在正常操作过程中重新启动,但可能需要从意外情况中恢复,例如尝试访问未映射的内存地址。在这些情况下,CHRE 会独立于 Android 重新启动。 HAL 通过RESTARTED事件通知 Android,它必须在 CHRE 重新初始化到可以接受新请求(例如queryApps()之后发送该事件。

CHRE系统概述

CHRE 是围绕事件驱动架构设计的,其中主要的计算单元是传递给 nanoapp 事件处理入口点的事件。虽然 CHRE 框架可以是多线程的,但给定的 nanoapp 永远不会从多个线程并行执行。 CHRE 框架通过三个 nanoapp 入口点之一( nanoappStart()nanoappHandleEvent()nanoappEnd() )或通过在先前的 CHRE API 调用中提供的回调与给定的 nanoapp 交互,并且 nanoapps 与 CHRE 框架交互并通过 CHRE API 的底层系统。 CHRE API 提供了一组基本功能以及用于访问上下文信号的工具,包括传感器、GNSS、Wi-Fi、WWAN 和音频,并且可以通过其他特定于供应商的功能进行扩展,以供特定于供应商的 nanoapps 使用.

构建系统

虽然 Context Hub HAL 和其他必要的 AP 端组件是与 Android 一起构建的,但在 CHRE 中运行的代码可能具有使其与 Android 构建系统不兼容的要求,例如需要专门的工具链。因此,AOSP 中的 CHRE 项目提供了一个基于 GNU Make 的简化构建系统来编译 nanoapps,并且可以选择将 CHRE 框架编译成可以与系统集成的库。添加对 CHRE 的支持的设备制造商应将针对其目标设备的构建系统支持集成到 AOSP 中。

CHRE API 是按照 C99 语言标准编写的,参考实现使用了适用于资源受限应用程序的 C++11 受限子集。

CHRE API

CHRE API 是一组 C 头文件,用于定义 nanoapp 和系统之间的软件接口。它旨在使 nanoapps 代码在支持 CHRE 的所有设备上兼容,这意味着 nanoapp 的源代码不需要修改以支持新的设备类型,尽管它可能需要专门针对目标设备的处理器重新编译指令集或应用程序二进制接口 (ABI)。 CHRE 架构和 API 设计还确保 nanoapps 在不同版本的 CHRE API 之间是二进制兼容的,这意味着 nanoapp 不需要重新编译即可在实现不同版本 CHRE API 的系统上运行编译 nanoapp 的目标 API。换句话说,如果 nanoapp 二进制文件在支持 CHRE API v1.3 的设备上运行,并且该设备升级为支持 CHRE API v1.4,则相同的 nanoapp 二进制文件将继续运行。类似地,nanoapp 可以在 CHRE API v1.2 上运行,并且可以在运行时确定它是否需要 API v1.3 中的功能来实现其功能,或者它是否可以运行,可能具有优雅的功能降级。

新版本的 CHRE API 与 Android 一起发布,但是由于 CHRE 实现是供应商实现的一部分,因此设备上支持的 CHRE API 版本不一定与 Android 版本相关联。

版本摘要

Android HIDL 版本控制方案一样,CHRE API 遵循语义版本控制。主要版本表示二进制兼容性,而次要版本在引入向后兼容功能时递增。 CHRE API 包括源代码注释,以识别哪个版本引入了函数或参数,例如@since v1.1

CHRE 实现还通过chreGetVersion()公开了特定于平台的补丁版本,它指示何时在实现中进行错误修复或次要更新。

版本 1.0 (Android 7)

包括对传感器和核心 nanoapp 功能(例如事件和计时器)的支持。

版本 1.1 (安卓 8)

通过 GNSS 位置和原始测量值、Wi-Fi 扫描和蜂窝网络信息引入定位功能,以及实现 nanoapp 到 nanoapp 通信的一般改进和其他改进。

版本 1.2 (Android 9)

添加对来自低功耗麦克风、Wi-Fi RTT 测距、AP 唤醒/睡眠通知和其他改进的数据的支持。

版本 1.3 (Android 10)

增强与传感器校准数据相关的功能,增加对按需刷新批量传感器数据的支持,定义步进检测传感器类型,并使用额外的精度字段扩展 GNSS 定位事件。

版本 1.4 (Android 11)

添加对 5G 小区信息、nanoapp 调试转储和其他改进的支持。

强制性系统功能

虽然上下文信号源(如传感器)被分类为可选功能区域,但所有 CHRE 实现都需要一些核心功能。这包括核心系统 API,例如用于设置计时器、向应用处理器上的客户端发送和接收消息、日志记录等的 API。有关完整详细信息,请参阅API 标头

除了在 CHRE API 中编码的核心系统功能外,还有在 Context Hub HAL 级别指定的强制性 CHRE 系统级功能。其中最重要的是动态加载和卸载 nanoapps 的能力。

C/C++ 标准库

为了最大限度地减少内存使用和系统复杂性,CHRE 实现需要仅支持标准 C 和 C++ 库和需要运行时支持的语言功能的子集。遵循这些原则,一些特性由于它们的内存和/或广泛的操作系统级依赖关系而被明确排除,而另一些特性则因为它们被更合适的 CHRE 特定 API 取代。虽然并非详尽的列表,但以下功能并不打算提供给 nanoapps:

  • C++ 异常和运行时类型信息 (RTTI)
  • 标准库多线程支持,包括 C++11 头文件<thread><mutex><atomic><future>
  • C 和 C++ 标准输入/输出库
  • C++ 标准模板库 (STL)
  • C++ 标准正则表达式库
  • 通过标准函数(例如malloccallocreallocfreeoperator new )和其他固有使用动态分配的标准库函数(例如std::unique_ptr )进行动态内存分配
  • 本地化和 Unicode 字符支持
  • 日期和时间库
  • 修改正常程序流程的函数,包括<setjmp.h><signal.h>abortstd::terminate
  • 访问宿主环境,包括system , getenv
  • POSIX 和其他未包含在 C99 或 C++11 语言标准中的库

在许多情况下,可以从 CHRE API 函数和/或实用程序库中获得等效的功能。例如, chreLog可用于针对 Android logcat 系统的调试日志记录,其中更传统的程序可能使用printfstd::cout

相反,需要一些标准库功能。平台实现可以通过静态库公开这些内容以包含在 nanoapp 二进制文件中,或者通过 nanoapp 和系统之间的动态链接来公开这些内容。这包括但不限于:

  • 字符串/数组实用程序: memcmpmemcpymemmovememsetstrlen
  • 数学库:常用的单精度浮点函数:

    • 基本操作: ceilf , fabsf , fmodf fmaxf fminf floorf roundf lroundf remainderf
    • 指数/幂函数: expflog2fpowfsqrtf
    • 三角/双曲函数: sinf , cosf , tanf , asinf , acosf , atan2f , tanhf

虽然一些底层平台支持附加功能,但 nanoapp 不被视为可跨 CHRE 实现移植,除非它将其外部依赖项限制为 CHRE API 函数和批准的标准库函数。

可选功能

为了促进硬件和软件,CHRE API 被划分为功能区域,从 API 的角度来看,这些功能区域被认为是可选的。虽然这些功能可能不需要支持兼容的 CHRE 实现,但可能需要它们来支持特定的 nanoapp。即使平台不支持给定的 API 集,引用这些函数的 nanoapps 也必须能够构建和加载。

传感器

CHRE API 提供从加速度计、陀螺仪、磁力计、环境光传感器和接近度等传感器请求数据的能力。这些 API 旨在提供类似于 Android 传感器 API 的功能集,包括支持批量传感器样本以降低功耗。与在 AP 上运行相比,在 CHRE 中处理传感器数据可实现对运动信号的低功耗和低延迟处理。

全球导航卫星系统

CHRE 提供用于从全球导航卫星系统 (GNSS) 请求位置数据的 API,包括 GPS 和其他卫星星座。这包括定期定位请求以及原始测量数据,尽管两者都是独立的功能。由于 CHRE 与 GNSS 子系统有直接链接,因此与基于 AP 的 GNSS 请求相比,功耗会降低,因为 AP 可以在定位会话的整个生命周期内保持睡眠状态。

无线上网

CHRE 提供与 Wi-Fi 芯片交互的能力,主要用于定位目的。虽然 GNSS 非常适用于室外位置,但 Wi-Fi 扫描的结果可以在室内和发达地区提供准确的位置信息。除了避免唤醒 AP 进行扫描的成本外,CHRE 还可以收听 Wi-Fi 固件执行的 Wi-Fi 扫描结果以用于连接目的,这些结果通常由于电源原因不会传送到 AP。将连接扫描用于上下文目的有助于减少执行的 Wi-Fi 扫描总数,从而节省电力。

CHRE API v1.1 中添加了对 Wi-Fi 的支持,包括监控扫描结果和按需触发扫描的能力。这些功能在 v1.2 中得到了扩展,能够针对支持该功能的接入点执行往返时间 (RTT)测量,从而实现准确的相对位置确定。

广域网

CHRE API 提供了检索服务小区及其邻居的小区标识信息的能力,这通常用于粗粒度定位目的。

声音的

CHRE 可以处理来自低功耗麦克风的批量音频数据,这通常利用用于实现 SoundTrigger HAL 的硬件。在 CHRE 中处理音频数据可以使其与其他数据融合,例如运动传感器。

参考实现

CHRE 框架的参考代码包含在 AOSP 的system/chre项目中,用 C++11 实现。虽然没有严格要求,但建议所有 CHRE 实现都基于此代码库,以帮助确保一致性并加速新功能的采用。这段代码可以看作是核心 Android 框架的类似物,因为它是应用程序使用的 API 的开源实现,用作兼容性的基准和标准。虽然可以使用特定于供应商的功能对其进行自定义和扩展,但建议将通用代码保持在尽可能接近参考的位置。与 Android 的 HAL 类似,CHRE 参考实现使用各种平台抽象来使其能够适应任何满足最低要求的设备。

有关技术细节和移植指南,请参阅system/chre项目中包含的自述文件。