Smartphones enthalten mehrere Prozessoren, die jeweils für die Ausführung verschiedener Aufgaben optimiert sind. Android wird jedoch nur auf einem Prozessor ausgeführt: dem Anwendungsprozessor (AP). Der AP ist für Anwendungsfälle mit eingeschaltetem Display wie Gaming optimiert, ist aber zu energiehungrig, um Funktionen zu unterstützen, die häufige, kurze Verarbeitungsvorgänge erfordern – auch wenn das Display ausgeschaltet ist. Kleinere Prozessoren können diese Arbeitslasten effizienter bewältigen und ihre Aufgaben erledigen, ohne die Akkulaufzeit merklich zu beeinträchtigen. Die Softwareumgebungen in diesen Low-Power-Prozessoren sind jedoch eingeschränkter und können stark variieren, was die plattformübergreifende Entwicklung erschwert.
Die Context Hub Runtime Environment (CHRE) bietet eine gemeinsame Plattform zum Ausführen von Apps auf einem Prozessor mit geringem Stromverbrauch und eine einfache, standardisierte, eingebettungsfreundliche API. Mit CHRE können Geräte-OEMs und ihre vertrauenswürdigen Partner die Verarbeitung ganz einfach vom AP auslagern, um Akku zu sparen und verschiedene Bereiche der Nutzerfreundlichkeit zu verbessern. Außerdem können sie eine Klasse von Always-on-Funktionen mit Kontextbezug aktivieren, insbesondere solche, bei denen maschinelles Lernen auf die Umgebungserkennung angewendet wird.
Schlüsselkonzepte
CHRE ist die Softwareumgebung, in der kleine native Apps, sogenannte Nano-Apps, auf einem Prozessor mit geringem Stromverbrauch ausgeführt werden und über die gemeinsame CHRE API mit dem zugrunde liegenden System interagieren. Um die korrekte Implementierung der CHRE-APIs zu beschleunigen, ist in AOSP eine plattformübergreifende Referenzimplementierung von CHRE enthalten. Die Referenzimplementierung umfasst gemeinsamen Code und Abstraktionen für die zugrunde liegende Hardware und Software über eine Reihe von Plattformabstraktionsebenen (Platform Abstraction Layers, PALs). Nano-Apps sind fast immer an eine oder mehrere Client-Apps gebunden, die unter Android ausgeführt werden und über ContextHubManager
-System-APIs mit eingeschränktem Zugriff mit CHRE und Nano-Apps interagieren.
Auf übergeordneter Ebene lassen sich Parallelen zwischen der Architektur von CHRE und Android insgesamt ziehen. Es gibt jedoch einige wichtige Unterschiede:
- CHRE unterstützt nur die Ausführung von Nano-Apps, die in nativem Code (C oder C++) entwickelt wurden. Java wird nicht unterstützt.
- Aufgrund von Ressourcenbeschränkungen und Sicherheitsbeschränkungen kann CHRE nicht von beliebigen Drittanbieter-Android-Apps verwendet werden. Nur Apps, die vom System als vertrauenswürdig eingestuft werden, können darauf zugreifen.
Außerdem ist es wichtig, zwischen dem Konzept von CHRE und einem Sensor-Hub zu unterscheiden. Es ist zwar üblich, dieselbe Hardware für die Implementierung des Sensor-Hubs und von CHRE zu verwenden, CHRE selbst bietet jedoch nicht die Sensorfunktionen, die vom Android Sensors HAL benötigt werden. CHRE ist an den Context Hub HAL gebunden und fungiert als Client eines gerätespezifischen Sensor-Frameworks, um Sensordaten zu empfangen, ohne den AP einzubeziehen.
Abbildung 1: CHRE-Framework-Architektur
Context Hub HAL
Die Hardwareabstraktionsschicht (HAL) des Context Hub ist die Schnittstelle zwischen dem Android-Framework und der CHRE-Implementierung des Geräts, die unter hardware/interfaces/contexthub
definiert ist.
Das Context Hub HAL definiert die APIs, über die das Android-Framework verfügbare Context Hubs und ihre Nano-Apps erkennt, über die Nachrichtenübermittlung mit diesen Nano-Apps interagiert und das Laden und Entladen von Nano-Apps ermöglicht. Eine Referenzimplementierung des Context Hub HAL, die mit der Referenzimplementierung von CHRE funktioniert, ist unter system/chre/host
verfügbar.
Im Falle eines Konflikts zwischen dieser Dokumentation und der HAL-Definition hat die HAL-Definition Vorrang.
Initialisierung
Beim Starten von Android ruft ContextHubService die HAL-Funktion getHubs()
auf, um festzustellen, ob auf dem Gerät Context Hubs verfügbar sind. Dies ist ein blockierender Einmalaufruf, der schnell abgeschlossen werden muss, um den Start nicht zu verzögern. Außerdem muss er ein genaues Ergebnis zurückgeben, da später keine neuen Kontext-Hubs eingeführt werden können.
Nano-Apps laden und entladen
Ein Context Hub kann eine Reihe von Nano-Apps enthalten, die im Geräte-Image enthalten sind und geladen werden, wenn CHRE gestartet wird. Diese werden als vorinstallierte Nano-Apps bezeichnet und sollten in der ersten möglichen Antwort auf queryApps()
enthalten sein.
Das Context Hub HAL unterstützt auch das dynamische Laden und Entladen von Nano-Apps zur Laufzeit über die Funktionen loadNanoApp()
und unloadNanoApp()
. Nano-Apps werden dem HAL in einem binären Format bereitgestellt, das für die CHRE-Hardware und die Softwareimplementierung des Geräts spezifisch ist.
Wenn beim Laden einer Nano-App das Schreiben in einen nichtflüchtigen Speicher erforderlich ist, z. B. in einen Flash-Speicher, der an den Prozessor angeschlossen ist, auf dem CHRE ausgeführt wird, muss die CHRE-Implementierung immer mit diesen dynamischen Nano-Apps im deaktivierten Zustand gestartet werden. Das bedeutet, dass kein Code der Nano-App ausgeführt wird, bis eine enableNanoapp()
-Anfrage über das HAL empfangen wird. Vorab geladene Nano-Apps können im aktivierten Zustand initialisiert werden.
Neustarts des Context Hub
Es wird nicht erwartet, dass CHRE während des normalen Betriebs neu gestartet wird. Es kann jedoch erforderlich sein, um sich von unerwarteten Bedingungen zu erholen, z. B. wenn versucht wird, auf eine nicht zugeordnete Speicheradresse zuzugreifen. In diesen Fällen wird CHRE unabhängig von Android neu gestartet. Das HAL benachrichtigt Android über das Ereignis RESTARTED
darüber. Dieses Ereignis darf erst gesendet werden, nachdem CHRE so weit reinitialisiert wurde, dass es neue Anfragen wie queryApps()
annehmen kann.
CHRE-System – Übersicht
CHRE basiert auf einer ereignisgesteuerten Architektur, bei der die primäre Recheneinheit ein Ereignis ist, das an den Ereignis-Handler-Einstiegspunkt einer Nano-App übergeben wird. Das CHRE-Framework kann zwar Multithreading unterstützen, eine bestimmte Nano-App wird jedoch nie parallel von mehreren Threads ausgeführt. Das CHRE-Framework interagiert mit einer bestimmten Nano-App über einen der drei Nano-App-Einstiegspunkte (nanoappStart()
, nanoappHandleEvent()
und nanoappEnd()
) oder über einen Callback, der in einem vorherigen CHRE-API-Aufruf bereitgestellt wurde. Nano-Apps interagieren mit dem CHRE-Framework und dem zugrunde liegenden System über die CHRE-API. Die CHRE API bietet eine Reihe von grundlegenden Funktionen sowie Möglichkeiten für den Zugriff auf kontextbezogene Signale, einschließlich Sensoren, GNSS, WLAN, WWAN und Audio. Sie kann mit zusätzlichen anbieterspezifischen Funktionen für die Verwendung durch anbieterspezifische Nano-Apps erweitert werden.
Build-System
Der Context Hub HAL und andere erforderliche AP-seitige Komponenten werden zusammen mit Android erstellt. Code, der im CHRE ausgeführt wird, kann jedoch Anforderungen haben, die ihn mit dem Android-Build-System inkompatibel machen, z. B. die Notwendigkeit einer speziellen Toolchain. Daher bietet das CHRE-Projekt in AOSP ein vereinfachtes Build-System auf Basis von GNU Make, um Nano-Apps und optional das CHRE-Framework in Bibliotheken zu kompilieren, die in das System integriert werden können. Gerätehersteller, die Unterstützung für CHRE hinzufügen, sollten die Build-Systemunterstützung für ihre Zielgeräte in AOSP integrieren.
Die CHRE API ist im C99-Sprachstandard geschrieben und die Referenzimplementierung verwendet eine eingeschränkte Teilmenge von C++11, die für ressourcenbeschränkte Apps geeignet ist.
CHRE API
Die CHRE API ist eine Sammlung von C-Headerdateien, die die Softwareschnittstelle zwischen einer Nano-App und dem System definieren. Es wurde entwickelt, um den Code von Nano-Apps auf allen Geräten, die CHRE unterstützen, kompatibel zu machen. Das bedeutet, dass der Quellcode einer Nano-App nicht geändert werden muss, um einen neuen Gerätetyp zu unterstützen. Er muss jedoch möglicherweise speziell für den Prozessor-Befehlssatz oder die Application Binary Interface (ABI) des Zielgeräts neu kompiliert werden. Die CHRE-Architektur und das API-Design sorgen auch dafür, dass Nano-Apps binärkompatibel mit verschiedenen Versionen der CHRE API sind. Das bedeutet, dass eine Nano-App nicht neu kompiliert werden muss, um auf einem System ausgeführt zu werden, das eine andere Version der CHRE API als die Ziel-API implementiert, für die die Nano-App kompiliert wurde. Wenn ein Nano-App-Binärprogramm auf einem Gerät ausgeführt wird, das CHRE API v1.3 unterstützt, und das Gerät auf CHRE API v1.4 aktualisiert wird, funktioniert dasselbe Nano-App-Binärprogramm weiterhin. Ebenso kann die Nano-App mit der CHRE API v1.2 ausgeführt werden und zur Laufzeit ermitteln, ob sie Funktionen aus der API v1.3 benötigt, um ihre Verwendung zu erreichen, oder ob sie möglicherweise mit einer sanften Funktionsverschlechterung ausgeführt werden kann.
Neue Versionen der CHRE API werden zusammen mit Android veröffentlicht. Da die CHRE-Implementierung jedoch Teil der Anbieterimplementierung ist, ist die auf einem Gerät unterstützte CHRE API-Version nicht unbedingt mit einer Android-Version verknüpft.
Zusammenfassung der Version
Wie das Android-HIDL-Versionsverwaltungsschema folgt die CHRE API der semantischen Versionsverwaltung.
Die Hauptversion gibt die binäre Kompatibilität an, während die Nebenversion erhöht wird, wenn abwärtskompatible Funktionen eingeführt werden. Die CHRE API enthält Quellcodeanmerkungen, um anzugeben, in welcher Version eine Funktion oder ein Parameter eingeführt wurde, z. B. @since v1.1
.
Die CHRE-Implementierung stellt auch eine plattformspezifische Patch-Version über chreGetVersion()
bereit, die angibt, wann Fehlerkorrekturen oder kleinere Updates in der Implementierung vorgenommen werden.
Version 1.0 (Android 7)
Unterstützt Sensoren und wichtige Nano-App-Funktionen wie Ereignisse und Timer.
Version 1.1 (Android 8)
Es werden Standortfunktionen über GNSS-Standort und Rohmessungen, WLAN-Scans und Mobilfunknetzinformationen eingeführt. Außerdem gibt es allgemeine Verbesserungen, um die Kommunikation zwischen Nano-Apps zu ermöglichen, und andere Verbesserungen.
Version 1.2 (Android 9)
Unterstützung für Daten von einem Mikrofon mit geringem Stromverbrauch, Wi-Fi RTT-Entfernungsmessung, AP-Aktivierungs- und ‑Ruhebenachrichtigungen sowie weitere Verbesserungen.
Version 1.3 (Android 10)
Die Funktionen für Sensorkalibrierungsdaten werden verbessert, die Unterstützung für das bedarfsgesteuerte Leeren von Batch-Sensordaten wird hinzugefügt, der Sensortyp für die Schrittzählung wird definiert und GNSS-Standort-Events werden um zusätzliche Genauigkeitsfelder erweitert.
Version 1.4 (Android 11)
Unterstützung für 5G-Zelleninformationen, Nanoapp-Debug-Dump und andere Verbesserungen wurden hinzugefügt.
Obligatorische Systemfunktionen
Quellen für Kontextsignale wie Sensoren werden in optionale Funktionsbereiche kategorisiert. Einige Kernfunktionen sind jedoch für alle CHRE-Implementierungen erforderlich. Dazu gehören APIs für das Kernsystem, z. B. zum Einstellen von Timern, zum Senden und Empfangen von Nachrichten an Clients auf dem Anwendungsprozessor und zum Protokollieren. Weitere Informationen finden Sie unter API-Headern.
Zusätzlich zu den in der CHRE API festgelegten Kernsystemfunktionen gibt es auch obligatorische CHRE-Systemfunktionen, die auf der Context Hub HAL-Ebene angegeben werden. Die wichtigste davon ist die Möglichkeit, Nano-Apps dynamisch zu laden und zu entladen.
C/C++-Standardbibliothek
Um die Speichernutzung und die Systemkomplexität zu minimieren, müssen CHRE-Implementierungen nur eine Teilmenge der Standard-C- und C++-Bibliotheken und Sprachfunktionen unterstützen, die Laufzeitunterstützung erfordern. Gemäß diesen Grundsätzen werden einige Funktionen aufgrund ihres Speicherbedarfs und der umfangreichen Abhängigkeiten auf Betriebssystemebene explizit ausgeschlossen. Andere werden ausgeschlossen, weil sie durch besser geeignete CHRE-spezifische APIs ersetzt werden. Die folgende Liste ist nicht vollständig, aber die folgenden Funktionen sind nicht für Nano-Apps vorgesehen:
- C++-Ausnahmen und Laufzeittypinformationen (RTTI)
- Unterstützung von Multithreading in der Standardbibliothek, einschließlich C++11-Headern
<thread>
,<mutex>
,<atomic>
,<future>
- Standard-E/A-Bibliotheken für C und C++
- C++ Standard Template Library (STL)
- C++-Standardbibliothek für reguläre Ausdrücke
- Dynamische Arbeitsspeicherzuweisung über Standardfunktionen (z. B.
malloc
,calloc
,realloc
,free
,operator new
) und andere Standardbibliotheksfunktionen, die von Natur aus eine dynamische Zuweisung verwenden, z. B.std::unique_ptr
- Unterstützung von Lokalisierung und Unicode-Zeichen
- Datums- und Uhrzeitbibliotheken
- Funktionen, die den normalen Programmablauf ändern, einschließlich
<setjmp.h>
,<signal.h>
,abort
,std::terminate
- Zugriff auf die Hostumgebung, einschließlich
system
,getenv
- POSIX- und andere Bibliotheken, die nicht in den Sprachstandards C99 oder C++11 enthalten sind
In vielen Fällen sind entsprechende Funktionen über CHRE API-Funktionen und Hilfsbibliotheken verfügbar. chreLog
kann beispielsweise für Debug-Logging verwendet werden, das auf das Android-Logcat-System ausgerichtet ist. In einem herkömmlichen Programm würde stattdessen printf
oder std::cout
verwendet werden.
Im Gegensatz dazu sind einige Funktionen der Standardbibliothek erforderlich. Es liegt an der Plattformimplementierung, diese über statische Bibliotheken für die Einbindung in eine Nano-App-Binärdatei oder durch dynamische Verknüpfung zwischen der Nano-App und dem System verfügbar zu machen. Dazu zählt unter anderem Folgendes:
- String- und Array-Hilfsprogramme:
memcmp
,memcpy
,memmove
,memset
,strlen
Mathematische Bibliothek: Häufig verwendete Gleitkommafunktionen mit einfacher Genauigkeit:
- Einfache Vorgänge:
ceilf
,fabsf
,floorf
,fmaxf
,fminf
,fmodf
,roundf
,lroundf
,remainderf
- Exponential- und Potenzfunktionen:
expf
,log2f
,powf
,sqrtf
- Trigonometrische und hyperbolische Funktionen:
sinf
,cosf
,tanf
,asinf
,acosf
,atan2f
,tanhf
- Einfache Vorgänge:
Einige zugrunde liegende Plattformen unterstützen zwar zusätzliche Funktionen, eine Nano-App gilt jedoch nur dann als auf verschiedenen CHRE-Implementierungen portierbar, wenn ihre externen Abhängigkeiten auf CHRE API-Funktionen und genehmigte Standardbibliotheksfunktionen beschränkt sind.
Optionale Funktionen
Zur Förderung von Hardware und Software ist die CHRE API in Funktionsbereiche unterteilt, die aus API-Sicht als optional gelten. Diese Funktionen sind möglicherweise nicht für eine kompatible CHRE-Implementierung erforderlich, aber für eine bestimmte Nano-App. Auch wenn eine Plattform eine bestimmte Gruppe von APIs nicht unterstützt, müssen Nano-Apps, die auf diese Funktionen verweisen, erstellt und geladen werden können.
Sensoren
Die CHRE API bietet die Möglichkeit, Daten von Sensoren wie Beschleunigungsmesser, Gyroskop, Magnetometer, Umgebungslichtsensor und Näherungssensor anzufordern. Diese APIs sollen einen ähnlichen Funktionsumfang wie die Android Sensors APIs bieten, einschließlich der Unterstützung für das Batching von Sensorproben zur Reduzierung des Stromverbrauchs. Die Verarbeitung von Sensordaten innerhalb von CHRE ermöglicht eine viel geringere Leistungsaufnahme und Latenz bei der Verarbeitung von Bewegungssignalen im Vergleich zur Ausführung auf dem AP.
GNSS
CHRE bietet APIs zum Anfordern von Standortdaten von einem GNSS (Global Navigation Satellite System), einschließlich GPS und anderer Satellitenkonstellationen. Dazu gehören Anfragen für regelmäßige Positionskorrekturen sowie Rohmessdaten. Beide sind jedoch unabhängige Funktionen. Da CHRE eine direkte Verbindung zum GNSS-Subsystem hat, wird der Stromverbrauch im Vergleich zu AP-basierten GNSS-Anfragen reduziert, da der AP während des gesamten Lebenszyklus einer Standortsitzung im Ruhemodus bleiben kann.
WLAN
Mit CHRE kann mit dem WLAN-Chip interagiert werden, hauptsächlich für Standortzwecke. GNSS funktioniert gut für Standorte im Freien, die Ergebnisse von WLAN-Scans können jedoch genaue Standortinformationen in Innenräumen und in bebauten Gebieten liefern. CHRE kann nicht nur die Kosten für das Aktivieren des AP für einen Scan vermeiden, sondern auch die Ergebnisse von WLAN-Scans abrufen, die von der WLAN-Firmware für Verbindungszwecke durchgeführt werden und aus Stromspargründen in der Regel nicht an den AP gesendet werden. Durch die Verwendung von Konnektivitätsscans für kontextbezogene Zwecke kann die Gesamtzahl der durchgeführten WLAN-Scans reduziert und somit Strom gespart werden.
In der CHRE API v1.1 wurde Unterstützung für WLAN hinzugefügt, einschließlich der Möglichkeit, Scanergebnisse zu überwachen und Scans bei Bedarf auszulösen. Diese Funktionen wurden in Version 1.2 erweitert. Nun können Umlaufzeitmessungen (Round-Trip Time, RTT) für Zugangspunkte durchgeführt werden, die die Funktion unterstützen. So lässt sich die relative Position genau bestimmen.
WWAN
Die CHRE API bietet die Möglichkeit, Informationen zur Zellidentifikation für die Serving Cell und ihre Nachbarzellen abzurufen. Dies wird in der Regel für die grobe Standortbestimmung verwendet.
Audio
CHRE kann Batches von Audiodaten von einem Mikrofon mit geringem Stromverbrauch verarbeiten, das in der Regel Hardware nutzt, die zur Implementierung des SoundTrigger-HAL verwendet wird. Durch die Verarbeitung von Audiodaten in CHRE können diese mit anderen Daten wie Bewegungssensoren zusammengeführt werden.
Referenzimplementierung
Der Referenzcode für das CHRE-Framework ist in AOSP im Projekt system/chre
enthalten und in C++11 implementiert. Es ist zwar nicht zwingend erforderlich, aber es wird empfohlen, dass alle CHRE-Implementierungen auf dieser Codebasis basieren, um die Konsistenz zu gewährleisten und die Einführung neuer Funktionen zu beschleunigen. Dieser Code kann als Analogon zum Android-Kernframework angesehen werden, da es sich um eine Open-Source-Implementierung von APIs handelt, die von Apps verwendet werden. Er dient als Grundlage und Standard für die Kompatibilität. Er kann zwar mit anbieterspezifischen Funktionen angepasst und erweitert werden, es wird jedoch empfohlen, den gemeinsamen Code so nah wie möglich am Referenzcode zu halten. Ähnlich wie bei den HALs von Android verwendet die CHRE-Referenzimplementierung verschiedene Plattformabstraktionen, damit sie an jedes Gerät angepasst werden kann, das die Mindestanforderungen erfüllt.
Technische Details und eine Anleitung zur Portierung finden Sie in der README-Datei, die im system/chre
-Projekt enthalten ist.