上下文中心運行時環境 (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項目中包含的自述文件。