智慧型手機內含多個處理器,每個處理器都針對不同的工作進行最佳化。不過,Android 只會在一個處理器上執行:應用程式處理器 (AP)。AP 經過調整,專為遊戲等螢幕用途提供絕佳效能,但因支援這類功能而需要頻繁、短暫的處理工作 (即使螢幕關閉),卻因太耗電而無法支援。更小的處理器可更有效率地處理這些工作負載,而且不會大幅影響電池續航力。不過,這些低功耗處理器的軟體環境較為受限,且可能有很大差異,因此跨平台開發作業較為困難。
Context Hub 執行階段環境 (CHRE) 提供通用平台,可在低功耗處理器上執行應用程式,並提供簡單、標準化且適合嵌入的 API。CHRE 可讓裝置原始設備製造商 (OEM) 和信任的合作夥伴輕鬆將處理作業從 AP 卸載,以節省電池電量並改善使用者體驗的各個層面,並啟用一類隨時運作且具備情境感知功能的功能,尤其是那些將機器學習應用於環境感測的功能。
核心概念
CHRE 是一種軟體環境,其中的小型原生應用程式 (稱為「nanoapps」) 會在低功耗處理器上執行,並透過常見的 CHRE API 與底層系統互動。為加快 CHRE API 的正確實作速度,我們在 Android 開放原始碼計畫中納入了 CHRE 的跨平台參照實作項目。參考實作項目包含常見程式碼,並透過一系列平台抽象層 (PAL) 將抽象化結構應用至基礎硬體和軟體。奈米應用程式幾乎總是與在 Android 中執行的一或多個用戶端應用程式綁定,這些應用程式會透過限制存取權 ContextHubManager
系統 API 與 CHRE 和奈米應用程式互動。
從整體來看,CHRE 和 Android 的架構之間有許多相似之處。不過,兩者之間仍有幾個重要差異:
- CHRE 僅支援以原生程式碼 (C 或 C++) 開發的 nanoapp,不支援 Java。
- 由於資源限制和安全性限制,CHRE 並未開放給任意第三方 Android 應用程式使用。只有系統信任的應用程式可以存取。
另外,請注意 CHRE 與感應器中樞的概念之間存在重要差異。雖然通常會使用相同的硬體來實作感應器中樞和 CHRE,但 CHRE 本身並未提供 Android Sensors HAL 所需的感應器功能。CHRE 會與 Context Hub HAL 綁定,並充當裝置專屬感應器架構的用戶端,以便接收感應器資料,而無須透過 AP。
圖 1. CHRE 架構架構
情境感知中樞 HAL
情境中心硬體抽象層 (HAL) 是 Android 架構與裝置 CHRE 實作項目之間的介面,如 hardware/interfaces/contexthub
所定義。Context Hub HAL 會定義 API,讓 Android 架構發現可用的 Context Hub 及其 NanoApp,透過訊息傳遞與這些 NanoApp 互動,並允許載入和卸載 NanoApp。如要查看可與 CHRE 參考實作項目搭配使用的 Context Hub HAL 參考實作項目,請前往 system/chre/host
。
如果本說明文件與 HAL 定義有所衝突,應以 HAL 定義為準。
初始化
當 Android 啟動時,ContextHubService 會叫用 getHubs()
HAL 函式,以判斷裝置上是否有任何情境中心。這是一個會造成封鎖的一次性呼叫,因此必須快速完成,以免延遲啟動,且必須傳回正確的結果,因為之後無法引入新的內容中心。
載入及卸載 nanoapp
情境中心可包含一組 nanoapp,這些 nanoapp 會納入裝置映像檔,並在 CHRE 啟動時載入。這些稱為預先載入的 nanoapp,應納入對 queryApps()
的第一個可能回應。
Context Hub HAL 也支援透過 loadNanoApp()
和 unloadNanoApp()
函式,在執行階段動態載入及卸載 nanoapp。系統會以二進位檔格式將 Nanoapp 提供給 HAL,該格式專屬於裝置的 CHRE 硬體和軟體實作。
如果載入 Nanoapp 的實作作業需要將其寫入非揮發性記憶體 (例如附加至執行 CHRE 的處理器的快閃儲存空間),則 CHRE 實作一律必須在停用狀態下使用這些動態奈米應用程式啟動。也就是說,除非透過 HAL 接收 enableNanoapp()
要求,否則不會執行任何 nanoapp 程式碼。預先載入的 nanoapp 可以在啟用狀態下初始化。
情境中心重新啟動
雖然在正常作業期間,CHRE 不會重新啟動,但可能需要從非預期的狀況中復原,例如嘗試存取未對應的記憶體位址。在這種情況下,CHRE 會獨立於 Android 重新啟動。HAL 會透過 RESTARTED
事件通知 Android 這項資訊,但必須等到 CHRE 重新啟動,且可接受新要求 (例如 queryApps()
) 時才可傳送。
CHRE 系統總覽
CHRE 專為事件導向架構設計,其中主要運算單位是傳遞至 nanoapp 事件處理進入點的事件。雖然 CHRE 架構可支援多執行緒,但特定的 nanoapp 絕不會從多個執行緒並行執行。CHRE 架構會透過三個 nanoapp 進入點 (nanoappStart()
、nanoappHandleEvent()
和 nanoappEnd()
) 或先前 CHRE API 呼叫中提供的回呼,與特定 nanoapp 互動,而 nanoapp 則會透過 CHRE API 與 CHRE 架構和基礎系統互動。CHRE API 提供一組基本功能和用於存取比對內容訊號的設施 (包括感應器、GNSS、Wi-Fi、WWAN 和音訊),也可以擴充供應商專屬的額外功能,供供應商專屬的奈米應用程式使用。
建構系統
雖然 Context Hub HAL 和其他必要的 AP 端元件會與 Android 一併建構,但在 CHRE 中執行的程式碼可能會因需求而與 Android 建構系統不相容,例如需要專門的工具鍊。因此,AOSP 中的 CHRE 專案提供了以 GNU Make 為基礎的簡易建構系統,可用於編譯 nanoapp,並視需要將 CHRE 架構納入可與系統整合的程式庫。如要新增 CHRE 支援功能,裝置製造商應將目標裝置的建構系統支援功能整合至 AOSP。
CHRE API 是依據 C99 語言標準編寫,參考實作項目則使用 C++11 的受限子集,適合資源有限的應用程式。
CHRE API
CHRE API 是 C 標頭檔案的集合,用於定義 nanoapp 與系統之間的軟體介面。這項功能旨在讓 nanoapp 程式碼在所有支援 CHRE 的裝置上相容,也就是說,nanoapp 的來源程式碼不需要修改就能支援新的裝置類型,但可能需要針對目標裝置的處理器指令集或應用程式二進位檔介面 (ABI) 專門重新編譯。CHRE 架構和 API 設計也能確保 nanoapp 在不同版本的 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 版 (Android 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 標頭。
除了 CHRE API 中編譯的核心系統功能之外,在 Context Hub HAL 層級也會指定必要的 CHRE 系統層級功能。其中最重要的是動態載入及卸載 nano 應用程式。
C/C++ 標準程式庫
為了盡量減少記憶體用量和系統複雜度,CHRE 實作項目只需支援標準 C 和 C++ 程式庫的子集,以及需要執行階段支援的語言功能。根據這些原則,我們明確排除部分功能,因為這些功能會占用大量的記憶體,且有許多作業系統層級的依附元件,而其他功能則是因為已被更適合的 CHRE 專屬 API 取代。以下功能雖然並非詳盡清單,但並不適用於奈米應用程式:
- C++ 例外狀況和執行階段類型資訊 (RTTI)
- 標準程式庫多執行緒支援,包括 C++11 標頭
<thread>
、<mutex>
、<atomic>
、<future>
- C 和 C++ 標準輸入/輸出程式庫
- C++ 標準範本程式庫 (STL)
- C++ 標準規則運算式程式庫
- 透過標準函式 (例如
malloc
、calloc
、realloc
、free
、operator new
) 進行動態記憶體配置,以及其他本身使用動態配置的標準程式庫函式 (例如std::unique_ptr
) - 本地化和萬國碼 (Unicode) 字元支援
- 日期和時間資料庫
- 修改一般程式流程的函式,包括
<setjmp.h>
、<signal.h>
、abort
、std::terminate
- 存取主機環境,包括
system
、getenv
- POSIX 和其他未納入 C99 或 C++11 語言標準的程式庫
在許多情況下,您可以透過 CHRE API 函式和公用程式庫取得等同的功能。舉例來說,chreLog
可用於針對 Android Logcat 系統的偵錯記錄,而較傳統的程式可能會使用 printf
或 std::cout
。
相反地,您必須具備某些標準程式庫功能。平台實作會透過靜態程式庫公開這些內容,以便納入 nanoapp 二進位檔,或是透過 nanoapp 和系統之間的動態連結。這類行為包括但不限於:
- 字串和陣列公用程式:
memcmp
、memcpy
、memmove
、memset
、strlen
數學程式庫:常用的單精度浮點函式:
- 基本作業:
ceilf
、fabsf
、floorf
、fmaxf
、fminf
、fmodf
、roundf
、lroundf
、remainderf
- 指數和冪函式:
expf
、log2f
、powf
、sqrtf
- 三角和雙曲線函式:
sinf
、cosf
、tanf
、asinf
、acosf
、atan2f
、tanhf
- 基本作業:
雖然部分基礎平台支援其他功能,但除非 nanoapp 將外部相依項目限制為 CHRE API 函式和核准的標準程式庫函式,否則無法在 CHRE 實作中移植。
選用功能
為了推廣硬體和軟體,CHRE API 分為功能區,從 API 的角度來看,這些功能區屬於選用。雖然這些功能可能不需要支援相容的 CHRE 實作,但可能需要支援特定的 nanoapp。即使平台不支援一組特定 API,參照這些函式的奈米應用程式仍要能建構和載入。
感應器
CHRE API 可讓您從加速計、陀螺儀、磁力計、環境光感應器和近距離感應器等感應器要求資料。這些 API 旨在提供類似 Android 感應器 API 的功能組合,包括支援感應器樣本批次處理,以減少耗電量。相較於 在 AP 上執行,在 CHRE 內處理感應器資料能夠大幅減少動作訊號的耗電量及延遲時間,進而縮短延遲時間。
GNSS
CHRE 提供 API,可用於要求全球衛星導航系統 (GNSS) 的定位資料,包括 GPS 和其他衛星群組。這包括要求定期位置修正,以及原始測量資料,但兩者都是獨立的功能。由於 CHRE 可直接連結至 GNSS 子系統,因此與以 AP 為基礎的 GNSS 要求相比,耗電量會降低,因為 AP 可以在位置工作階段的整個生命週期中保持休眠狀態。
Wi-Fi
CHRE 可與 Wi-Fi 晶片互動,主要用於定位目的。雖然 GNSS 適用於戶外位置,但 Wi-Fi 掃描結果可在室內和開發區提供準確的位置資訊。除了避免喚醒無線基地台進行掃描的成本外,CHRE 還可監聽 Wi-Fi 韌體執行 Wi-Fi 掃描作業的結果,以便連線,這些結果通常不會因電力因素而傳送至無線基地台。利用連線掃描來判斷情境,有助於減少執行的 Wi-Fi 掃描總數,進而節省電力。
CHRE API 1.1 版已新增對 Wi-Fi 的支援,包括監控掃描結果,並依需求觸發掃描作業。我們在 1.2 版中擴充了這些功能,可針對支援功能的存取點執行封包往返時間 (RTT) 測量,以便精確判斷相對位置。
WAN
CHRE API 可擷取服務區塊及其鄰近區塊的區塊 ID 資訊,通常用於粗略位置目的。
音訊
CHRE 可處理低功耗麥克風的音訊資料批次,這些麥克風通常會利用用於實作 SoundTrigger HAL 的硬體。在 CHRE 中處理音訊資料,可將音訊資料與其他資料 (例如動作感應器) 融合。
參考實作
CHRE 架構的參考程式碼已納入 Android 開放原始碼計畫的 system/chre
專案 (以 C++11 實作)。雖然這並非強制規定,但建議所有 CHRE 實作都以這個程式碼集為基礎,藉此確保一致性並加速採用新功能。這段程式碼可視為 Android 核心架構的類似項目,因為它是應用程式使用的 API 開放原始碼實作項目,可做為相容性的基準和標準。雖然您可以使用特定供應商的功能自訂和擴充,但建議您盡可能將常用程式碼維持在參考範圍內。與 Android 的 HAL 類似,CHRE 參考實作項目會使用各種平台抽象化,以便將其調整為符合最低需求的任何裝置。
如需技術詳細資料和移植指南,請參閱 system/chre
專案中的 README。