スマートフォンには、多数のプロセッサが搭載されており、これらのプロセッサはさまざまなタスクを実行するためにそれぞれ最適化されています。ただし、Android はアプリケーション プロセッサ(AP)という 1 つのプロセッサでのみ動作します。AP は、ゲームなどの画面オンのユースケースでの優れたパフォーマンスを実現することを重点に置いていますが、画面がオフあっても常に頻繁かつ短期的に集中する処理を必要とする機能をサポートするには、あまりにも電力が不足しています。プロセッサが小さいほど、これらの作業負荷をより効率的に処理し、電池寿命に大きな影響を与えることなくタスクを完了できるようになります。ただし、こうした低消費電力プロセッサのソフトウェア環境は制限されており、状況によって大きく異なるため、クロス プラットフォームの開発が難しくなることがあります。
Context Hub Runtime Environment(CHRE)は、低消費電力プロセッサでアプリを実行するための共通プラットフォームを提供し、埋め込みに配慮したシンプルで標準化された API を統合します。CHRE を使用すると、デバイス OEM とその信頼できるパートナーは、AP からの処理をオフロードして、電力を節約し、ユーザー エクスペリエンスをあらゆる側面で向上させることができます。また常時稼働のコンテンツ ターゲット機能、特に機械学習のアンビエント センシングへの応用を伴う機能もサポートしています。
主な概念
CHRE は、nanoapps という小さなネイティブ アプリを低消費電力プロセッサ上で実行し、共通の CHRE API を介して基盤となるシステムとやり取りできるようにするソフトウェア環境です。CHRE API の適切な実装を高速化するため、CHRE のクロスプラットフォーム リファレンス実装が AOSP に含まれています。リファレンス実装には、一般的なコードと、一連のプラットフォーム抽象化レイヤ(PAL)を通じた、基盤となるハードウェアとソフトウェアに対する抽象化が含まれています。nanoapps は多くの場合、Android で実行されている 1 つ以上のクライアント アプリに関連付けられています。これらのアプリは、アクセスが制限された ContextHubManager システム API を介して CHRE や nanoapps とやり取りします。
簡単に言えば、CHRE のアーキテクチャと Android は全体的に似ています。ただし、以下のような重要な違いがあります。
- CHRE は、ネイティブ コード(C または C++)で開発された nanoapp のみを実行できます。Java はサポートしていません。
- リソースの制約とセキュリティ上の制限により、CHRE はすべてのサードパーティ Android アプリで使用できるわけではありません。システムが信頼するアプリのみがアクセスできます。
CHRE とセンサーハブの概念との間にも重要な違いがあります。センサーハブと CHRE は同じハードウェアで実装するのが一般的ですが、CHRE 自体は、Android センサー HAL に必要なセンサー機能を提供しません。CHRE は Context Hub HAL と関連付けられており、デバイス固有のセンサー フレームワークのクライアントとして機能し、AP を使用せずにセンサーデータを受信します。
図 1. CHRE フレームワーク アーキテクチャ
Context Hub HAL
Context Hub Hardware Abstraction Layer(HAL)は、Android フレームワークとデバイスの CHRE 実装の間のインターフェースであり、hardware/interfaces/contexthub
で定義されています。Context Hub HAL は、Android フレームワークが、利用可能なコンテキスト ハブとその nanoapp の検出、メッセージの受け渡しを通じたそれらの nanoapp とのやり取り、nanoapp のロードとアンロードを可能にする API を定義しています。CHRE のリファレンス実装で動作する Context Hub HAL のリファレンス実装については、system/chre/host
をご覧ください。
このドキュメントと HAL 定義の間に矛盾がある場合は、HAL 定義が優先します。
初期化
Android が起動すると、ContextHubService は getHubs()
HAL 関数を呼び出して、デバイスで使用できるコンテキスト ハブがあるかどうかを判断します。これは 1 回限りのブロッキング呼び出しであるため、起動の遅延を回避するために迅速に完了する必要があります。また新しいコンテキスト ハブを後から導入できないので、正確な結果を返す必要があります。
nanoapp のロードとアンロード
コンテキスト ハブには、デバイス イメージに含まれており、CHRE の起動時にロードされる nanoapp のセットを含めることができます。これはプリロードされた nanoapps と呼ばれ、queryApps()
への最初のレスポンスに含める必要があります。
Context Hub HAL では、実行時に loadNanoApp()
関数と unloadNanoApp()
関数を通じて、nanoapp を動的にロードおよびアンロードすることもできます。nanoapp は、デバイスの CHRE のハードウェア実装とソフトウェア実装に固有のバイナリ形式で HAL に提供されます。
nanoapp をロードする実装で、不揮発性メモリ(CHRE を実行しているプロセッサに接続されたフラッシュ ストレージなど)への書き込みを行う場合、CHRE 実装は常に、これらの動的 nanoapp が無効な状態で起動する必要があります。つまり、HAL から enableNanoapp()
リクエストを受信するまで、nanoapp のコードは実行されません。プリロードされた nanoapp は、有効な状態で初期化できます。
Context Hub の再起動
通常のオペレーション中に CHRE が再起動することはありませんが、マッピングされていないメモリアドレスへにアクセスしようとするなど、予期しない条件からの復元が必要になることがあります。このような状況では、CHRE は Android とは独立して再起動します。HAL はこの状況を RESTARTED
イベントを通じて Android に通知します。このイベントは、CHRE が新しいリクエスト(queryApps()
など)を受け入れることができるよう、再初期化された後にのみ送信する必要があります。
CHRE システムの概要
CHRE はイベント ドリブンなアーキテクチャを中心に設計されており、コンピューティングのメインユニットは nanoapp のイベント処理エントリ ポイントに渡されるイベントです。CHRE フレームワークはマルチスレッドにすることができますが、特定の nanoapp が複数のスレッドから並列に実行されることはありません。CHRE フレームワークは、3 つの nanoapp エントリ ポイント(nanoappStart()
、nanoappHandleEvent()
、nanoappEnd()
)の 1 つ、または以前の CHRE API 呼び出しで提供されたコールバックを介して、特定の nanoapp とやり取りします。nanoapp は CHRE API を介して CHRE フレームワークおよび基盤となるシステムとやり取りします。CHRE API は、一連の基本的な機能に加え、コンテキスト シグナル(センサー、GNSS、Wi-Fi、WWAN、音声など)にアクセスするための機能も提供します。CHRE API は、他のベンダー固有の機能で拡張してベンダー固有の nanoapp で使用できます。
ビルドシステム
Context Hub HAL などの必要な AP 側のコンポーネントは Android とともにビルドされますが、CHRE 内で実行されるコードには、Android ビルドシステムとの互換性をなくす要件(特殊なツールチェーンが必要になるなど)が含まれる場合があります。したがって、AOSP の CHRE プロジェクトは、GNU Make に基づく簡略化されたビルドシステムを提供し、nanoapp と CHRE フレームワーク(必要な場合)をシステムと統合できるライブラリにコンパイルします。CHRE のサポートを追加するデバイス メーカーは、ターゲット デバイスのビルドシステム サポートを AOSP に統合する必要があります。
CHRE API は C99 言語標準で記述されており、リファレンス実装ではリソース制限のあるアプリに適した C++11 の制限付きサブセットを使用します。
CHRE API
CHRE API は、nanoapp とシステムの間のソフトウェア インターフェースを定義する C ヘッダー ファイルのコレクションです。CHRE API は、CHRE をサポートするすべてのデバイスに nanoapp コードとの互換性を持たせるように設計されています。つまり、新しいデバイスタイプをサポートするために nanoapp のソースコードを修正する必要はありません。ただし、ターゲット デバイスのプロセッサ命令セットやアプリケーション バイナリ インターフェース(ABI)に合わせて nanoapp のソースコードを再コンパイルする必要が生じることがあります。また、CHRE アーキテクチャと API 設計により、nanoapp が CHRE API の異なるバージョン間でバイナリ互換性があることが保証されます。つまり、実装された CHRE API がターゲット API(nanoapp のコンパイル先)とは異なるバージョンのシステムで実行する場合でも、nanoapp を再コンパイルする必要はありません。言い換えれば、nanoapp バイナリが CHRE API v1.3 をサポートするデバイスで実行され、そのデバイスが CHRE API v1.4 をサポートするようにアップグレードされた場合でも、その nanoapp バイナリは引き続き同じように動作します。同様に、nanoapp は CHRE API v1.2 で実行でき、実行時に、nanoapp を機能させるために API v1.3 の機能が必要かどうか、または nanoapp が機能を適切に低下させることで正常に動作できるかかどうかを判断できます。
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 間の通信などの改善を図るための一般的な最適化を行いました。
バージョン 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 システムレベルの機能もあります。これらのうち最も重要な機能は、nanoapp を動的にロードおよびアンロードすることです。
C/C++ 標準ライブラリ
メモリ使用量とシステムの複雑さを最小限に抑えるために、CHRE 実装は、標準の C および C++ ライブラリの一部と、ランタイム サポートを必要とする言語機能のみをサポートする必要があります。上記の原則に従い、一部の機能はメモリや OS レベルの広範な依存関係により明示的に除外されますが、その他の機能は、より適切な CHRE 固有の API に置き換えられます。以下にリストされている機能(すべてを網羅するものではありません)は、nanoapp を対象としていません。
- 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
などのホスト環境へのアクセス- C99 または C++11 言語標準に含まれていない POSIX などのライブラリ
多くの場合、同等の機能は 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 関数と承認された標準ライブラリ関数に制限する場合を除き、nanoapp は CHRE 実装間で移植可能とはみなされません。
オプション機能
CHRE API は、ハードウェアとソフトウェアを改善するために、複数の機能領域に分割されており、これらの機能は API からは省略可とみなされます。これらの機能は互換性のある CHRE 実装をサポートするために必要とは限りませんが、特定の nanoapp のサポートに必要となる場合があります。プラットフォームが特定の API のセットをサポートしていない場合でも、これらの関数を参照する nanoapps を構築してロードできなければなりません。
センサー
CHRE API は、加速度計、ジャイロスコープ、磁力計、周囲光センサー、近接センサーなどのセンサーからのデータをリクエストできます。これらの API は、電力消費を削減するためのセンサー サンプルの一括処理のサポートなど、Android センサー API に類似した機能セットを提供することを目的としています。CHRE 内でセンサーデータを処理すると、AP で実行する場合と比べて、モーション シグナル処理時の消費電力とレイテンシを大幅に削減できます。
GNSS
CHRE は、GPS やその他の衛星コンステレーションなど、グローバル ナビゲーション衛星システム(GNSS)から位置情報をリクエストするための API を提供します。これには、定期的な位置修正と生の測定データのリクエストが含まれますが、どちらも独立した機能です。CHRE は GNSS サブシステムに直接リンクしていることから、AP は位置情報セッションのライフサイクル全体にわたってスリープ状態を維持できるので、AP ベースの GNSS リクエストよりも消費電力が削減されます。
Wi-Fi
CHRE は、主に位置情報の目的で Wi-Fi チップと交信できる機能を提供します。GNSS は屋外の場所でうまく機能しますが、Wi-Fi スキャンの結果は、屋内や開発エリアで正確な位置情報を提供できます。CHRE は、スキャンのために AP をウェイクアップするコストを節約するだけでなく、接続の目的で WLAN ファームウェアによって実行された WLAN スキャン結果をリッスンすることもできます。電力を節約するために、スキャン結果は通常 AP に送信されません。状況に応じて接続スキャンを使用すると、実行される Wi-Fi スキャンの総数を減らすことができ、それにより電力が節約されます。
CHRE API v1.1 では、スキャン結果をモニタリングし、オンデマンドでスキャンをトリガーする機能を含む WLAN のサポートを追加しました。これらの機能は、v1.2 で拡張されており、この機能をサポートするアクセス ポイントに対してラウンド トリップ時間(RTT)測定を行い、相対位置を正確に決定できるようになりました。
WWAN
CHRE API は、サービングセルとその隣接セルのセル識別情報を取得でき、セル識別情報は通常、大まかな位置の特定に使用されます。
音声
CHRE は、低電力マイクからの大規模な音声データを処理でき、これには通常、SoundTrigger HAL の実装に使用されるハードウェアが利用されます。音声データを CHRE で処理すると、モーション センサーなどの他のデータと融合できます。
リファレンス実装
CHRE フレームワークのリファレンス コードは、C++11 で実装されている system/chre
プロジェクトの AOSP に含まれています。厳密には必須ではありませんが、すべての CHRE 実装をこのコードベースに基づいて作成することをおすすめします。これにより、実装の一貫性が維持され、新しい機能の迅速な導入が可能になります。このコードは、アプリで使用される API のオープンソース実装であり、互換性のベースラインや標準として機能するので、コア Android フレームワークと類似しているとみなすことができます。ベンダー固有の機能を使用してカスタマイズと拡張が可能ですが、共通コードを参照コードにできるだけ近づけることをおすすめします。Android の HAL と同様に、CHRE リファレンス実装では、さまざまなプラットフォーム抽象化を使用して、最小要件を満たす任意のデバイスに適応できるようにしています。
技術的な詳細と移植ガイドについては、system/chre
プロジェクトに含まれる README をご覧ください。