センサー スタック

以下の図は Android のセンサー スタックを示しています。各コンポーネントは直接隣接するコンポーネントとのみ通信しますが、一部のセンサーはセンサーハブをバイパスできます(センサーハブがある場合)。制御はアプリケーションからセンサーの方向に流れ、データはセンサーからアプリケーションの方向に流れます。

Android のセンサー スタックのレイヤとオーナー

図 1: Android のセンサー スタックのレイヤとそれぞれのオーナー

SDK

アプリケーションは Sensors SDK(Software Development Kit)API を介してセンサーにアクセスします。この SDK には、使用可能なセンサーを一覧表示し、いずれかのセンサーに登録するための関数が含まれています。

センサーに登録すると、望ましいサンプリング頻度とレイテンシに関する要件がアプリケーションにより指定されます。

  • たとえば、アプリケーションがデフォルトの加速度計に登録し、100 Hz の頻度でイベントを要求し、1 秒のレイテンシでイベントを報告するように指定する場合などがあります。
  • アプリケーションは、100 Hz 以上の頻度で加速度計からイベントを受信します。この場合、最大で 1 秒のレイテンシが発生します。

SDK について詳しくは、デベロッパー向けドキュメントをご覧ください。

フレームワーク

フレームワークは、複数のアプリケーションを HAL にリンクします。HAL 自体は単一のクライアントです。フレームワーク レベルのこの多重化がなければ、それぞれのセンサーに同時にアクセスできるのは 1 つのアプリケーションのみになります。

  • あるアプリケーションが最初にあるセンサーに登録すると、フレームワークは HAL にそのセンサーをアクティブにするためのリクエストを送信します。
  • 別のアプリケーションが同じセンサーに登録すると、フレームワークはそれぞれのアプリケーションが指定する要件を考慮して、要求されたパラメータを更新して HAL に送信します。
    • サンプリング頻度については、複数のアプリケーションから要求された中で最大の頻度が HAL に送信されます。つまり、一部のアプリケーションは、要求された頻度より高い頻度でイベントを受信します。
    • 最大レポート レイテンシについては、複数のアプリケーションから要求された中で最小のレイテンシが HAL に送信されます。あるアプリケーションが、あるセンサーを最大レポート レイテンシを 0 に指定してリクエストした場合、別のアプリケーションがこのセンサーを 0 以外の値の最大レポート レイテンシでリクエストしたとしても、すべてのアプリケーションは連続モードでこのセンサーからイベントを受信します。詳細については、バッチ処理をご覧ください。
  • あるセンサーに登録したアプリケーションが最後にそのセンサーへの登録を解除すると、フレームワークは HAL にセンサーを停止するためのリクエストを送信し、電力が不要に消費されないようにします。

多重化の影響

フレームワークには多重化レイヤが必要であり、これは、設計における判断に影響します。

  • アプリケーションが特定のサンプリング頻度を要求している場合でも、より高い頻度でイベントが受信されることがあります。別のアプリケーションが同じセンサーをより高い頻度で要求している場合、最初のアプリケーションでもより高い頻度でイベントが受信されます。
  • 要求される最大レポート レイテンシにも同じことが当てはまります。アプリケーションは、要求しているレイテンシよりもはるかに短いレイテンシでイベントを受信する場合があります。
  • サンプリング頻度と最大レポート レイテンシ以外のセンサー パラメータをアプリケーションから設定することはできません。
    • たとえば、「高精度」モードと「低電力」モードの両方で機能する物理的なセンサーを考えてみましょう。
    • Android デバイスでは、この 2 つのモードのうちの 1 つのみを使用できます。これは、(そうでない場合に)あるアプリケーションが高精度モードを要求し、別のアプリケーションが低電力モードを要求する状況が発生する可能性があるためであり、このフレームワークで両方のアプリケーションの要求を満たすことができないためです。フレームワークは常にすべてのクライアントの要求を満たす必要があるため、これは実現できません。
  • アプリケーションからセンサーやそのドライバにデータを送信することはできません。これは、センサーの動作がアプリケーションにより変更されて他のアプリケーションが破損することを防止するためのものです。

センサー フュージョン

Android フレームワークでは、一部の複合センサーのデフォルト実装が提供されています。たとえば、ジャイロスコープ加速度計磁力計がデバイスに搭載されているが、回転ベクトル センサー重力センサーリニア加速度センサーが搭載されていない場合には、フレームワークでこれらのセンサーの実装が用意されているため、アプリケーションは引き続きこれらのセンサーを使用できます。

デフォルト実装は、他の実装がアクセスできるすべてのデータにアクセスできるわけではありません。また、SoC で実行する必要があるため、他の実装ほど正確ではなく、電力効率も良くありません。デバイス メーカーは可能な限り、このデフォルト実装に依存するのではなく、独自の複合センサー(回転ベクトル センサー、重力センサー、リニア加速度センサーや、ゲーム回転ベクトルなどの新しい複合センサーなど)を用意する必要があります。また、デバイス メーカーは、センサーチップのベンダーに実装をリクエストすることもできます。

デフォルトのセンサー フュージョンの実装は管理されていません。そのため、この実装に依存するデバイスは CTS に失敗する可能性があります。

詳細

このセクションでは、Android オープンソース プロジェクト(AOSP)のフレームワーク コードの管理を行う方向けに背景情報を説明します。ハードウェア メーカー向けの情報ではありません。

JNI

このフレームワークは、android.hardware に関連付けられた、frameworks/base/core/jni/ ディレクトリに存在する Java Native Interface(JNI)を使用します。このコードは下位レベルのネイティブ コードを呼び出して、センサー ハードウェアへのアクセス権を取得します。

ネイティブ フレームワーク

ネイティブ フレームワークは frameworks/native/ で定義されており、android.hardware パッケージに相当するネイティブの機能を提供します。ネイティブ フレームワークは Binder IPC プロキシを呼び出して、センサー固有のサービスへのアクセス権を取得します。

Binder IPC

Binder IPC プロキシは、プロセスの境界を越えた通信を容易にします。

HAL

Sensors Hardware Abstraction Layer (HAL) API は、ハードウェア ドライバと Android フレームワーク間のインターフェースです。HAL は、1 つの HAL インターフェース(sensors.h)と 1 つの HAL 実装(sensors.cpp)で構成されています。

このインターフェースは Android と AOSP のコントリビューターにより定義され、実装はデバイスのメーカーにより提供されます。

センサー HAL インターフェースは hardware/libhardware/include/hardware にあります。詳細については、sensors.h をご覧ください。

リリース サイクル

HAL 実装は、your_poll_device.common.version を設定することにより、実装する HAL インターフェースのバージョンを指定します。既存の HAL インターフェース バージョンは sensor.h で定義され、それらのバージョンに機能が関連付けられています。

Android フレームワークは現在バージョン 1.0 と 1.3 をサポートしていますが、1.0 はまもなくサポートが終了します。このドキュメントでは、バージョン 1.3 の動作について説明します(すべてのデバイスで、バージョン 1.3 にアップグレードすることが推奨されます)。1.3 にアップグレードする方法については、HAL バージョンのサポート終了をご覧ください。

カーネル ドライバ

センサー ドライバは、物理デバイスとの通信を行います。HAL 実装とドライバが同じソフトウェア エンティティである場合もあります。また、ハードウェア インテグレータが、センサーチップのメーカーにドライバの提供をリクエストする場合もありますが、HAL の実装はハードウェア インテグレータが行います。

いずれにせよ、HAL の実装とカーネル ドライバはハードウェア メーカーの責任となります。Android は、このような作成を行うための適切な手段を提供していません。

センサーハブ

デバイスのセンサー スタックには、オプションでセンサーハブを含めることができます。これは、SoC を一時停止モードにした状態で、低レベルの計算を低電力で行うのに役立ちます。たとえば、歩数のカウントやセンサー フュージョンをチップ上で行えるようになります。また、センサーハブにセンサーのバッチ処理機能を実装することで、センサー イベントのハードウェア FIFO を実現できます。詳細については、バッチ処理をご覧ください。

注: 新しいセンサーや LED を使用する新しい ContextHub 機能を開発する場合、Hikey または Hikey960 開発ボードに接続された Neonkey SensorHub も使用できます。

センサーハブがどのように実装されるかに関しては、アーキテクチャによって異なります。センサーハブが独立した 1 つのチップとして実装されることも、SoC と同じチップ上に搭載されることもあります。また、センサーハブの重要な特徴として、バッチ処理のための十分なメモリを搭載していることと、消費電力が非常に少なく、低電力の Android センサーを実現できることがあります。一部のセンサーハブには、一般的な計算用のマイクロコントローラと、低電力センサー用のきわめて低電力な計算を実現するハードウェア アクセラレータが搭載されています。

センサーハブのアーキテクチャ、およびセンサーや SoC(I2C バス、SPI バスなど)との通信方法は Android により指定されていませんが、全体としての電力消費量を最小限に抑えることを目的とすることが理想です。

実装の簡素化に大きな影響を与えると思われるオプションの 1 つは、センサーハブから SoC に向かう 2 つの割り込みラインを用意することです。1 つは起動割り込み用(起動センサー用)、もう 1 つは非起動割り込み用です(非起動センサー用)。

センサー

センサーは、測定値を生成する物理的な MEMS チップです。多くの場合、同じチップ上に複数の物理センサーがあります。たとえば、加速度計、ジャイロスコープ、磁力計が搭載されたチップなどです(このようなチップは、各センサーが 3 軸でデータを提供するため、9 軸チップと呼ばれることもあります)。

これらのチップには、モーション検出、歩数検出、9 軸センサー フュージョンなどの一般的計算を行うためのロジックが搭載されているものもあります。

CDD の電力と精度に関する要件と推奨事項は、物理センサーではなく Android センサーを対象としていますが、これらの要件は物理センサーの選択に影響します。たとえば、ゲーム回転ベクトルの精度に関する要件は、物理的なジャイロスコープに求められる精度に影響します。物理センサーに関する要件を考案する責任はデバイス メーカーにあります。