blob: 6bc3b9978043dc9e6ffc65793677389717dafc8b [file] [log] [blame]
<html devsite><head>
<title>传感器堆栈</title>
<meta name="project_path" value="/_project.yaml"/>
<meta name="book_path" value="/_book.yaml"/>
</head>
<body>
<!--
Copyright 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>下图显示的是 Android 传感器堆栈。尽管某些传感器可以绕过传感器中枢(如果存在)进行通信,但各个组件仅可与其上方和下方紧邻的组件通信。控制系统从应用向下流向传感器,数据从传感器向上流向应用。</p>
<img src="images/ape_fwk_sensors.png" alt="Android 传感器堆栈的层级和所有者"/>
<p class="img-caption"><strong>图 1. </strong> Android 传感器堆栈层级以及各自的所有者</p>
<h2 id="sdk">SDK</h2>
<p>应用通过 <a href="http://developer.android.com/reference/android/hardware/SensorManager.html">Sensors SDK(软件开发套件)API</a> 访问传感器。SDK 包含用以列示可用传感器和注册到传感器的函数。</p>
<p>在注册到传感器时,应用可指定自己的首选采样率和延迟要求。</p>
<ul>
<li>例如,应用可注册到默认加速度计,以 100Hz 的频率请求事件,并允许事件报告有 1 秒延迟。</li>
<li>应用将以至少 100Hz 的频率从加速度计接收事件,且最多会延迟 1 秒。</li>
</ul>
<p>请参阅<a href="index.html#targeted_at_developers">开发者文档</a>,详细了解 SDK。</p>
<h2 id="framework">框架</h2>
<p>框架负责将多个应用关联到 <a href="hal-interface.html">HAL</a>。HAL 本身是单一客户端。如果框架级别没有发生这种多路复用,则在任何指定时间内只有一个应用可以访问各个传感器。</p>
<ul>
<li>当第一个应用注册到传感器时,框架会向 HAL 发送请求以激活传感器。</li>
<li>当其他应用注册到相同的传感器时,框架会考虑每个应用的要求,并将更新的已请求参数发送到 HAL。<ul>
<li><a href="hal-interface.html#sampling_period_ns">采样率</a>将是请求的采样率的最大值,这意味着一些应用接收事件的频率会高于所请求的频率。</li>
<li><a href="hal-interface.html#max_report_latency_ns">最大报告延迟</a>将是请求的延迟的最小值。如果某个应用以 0 为最大报告延迟请求传感器,则所有应用将以连续模式从该传感器接收事件,即使某些应用以非零值的最大报告延迟请求传感器也是如此。请参阅<a href="batching.html">批处理</a>,了解详情。</li>
</ul>
</li>
<li>当注册到某个传感器的最后一个应用取消注册之后,框架会向 HAL 发送请求以停用该传感器,从而避免不必要的功耗。</li>
</ul>
<h3 id="impact_of_multiplexing">多路复用的影响</h3>
<p>在框架中实现多路复用层的这一需求解释了一些设计决策。</p>
<ul>
<li>当应用请求特定采样率时,不能保证事件不会以更快的频率到达。如果另一个应用以更快的频率请求同一传感器,则第一个应用也将以较快频率接收事件。</li>
<li>请求的最大报告延迟同样无法得到保证:应用可能以比请求的延迟短的多的延迟接收事件。</li>
<li>除了采样率和最大报告延迟之外,应用还无法配置传感器参数。
<ul>
<li>例如,假设某个物理传感器可同时在“高精确度”和“低电耗”模式下运行。</li>
<li>这两种模式中只有一种可以在 Android 设备上使用,因为否则一个应用可能请求高精确度模式,而另一个可能请求低电耗模式;框架根本无法同时满足这两个应用的要求。框架必须始终能够满足所有客户端的需要,因此同时使用两种模式是不可行的。</li>
</ul>
</li>
<li>没有将数据从应用向下发送至传感器或其驱动程序的机制。这样可以确保某个应用无法修改传感器的行为,从而不会对其他应用造成破坏。</li>
</ul>
<h3 id="sensor_fusion">传感器融合</h3>
<p>Android 框架为部分复合传感器提供默认实现。如果设备上有<a href="sensor-types.html#gyroscope">陀螺仪</a><a href="sensor-types.html#accelerometer">加速度计</a><a href="sensor-types.html#magnetic_field_sensor">磁力计</a>,但没有<a href="sensor-types.html#rotation_vector">旋转矢量</a><a href="sensor-types.html#gravity">重力</a><a href="sensor-types.html#linear_acceleration">线性加速度</a>传感器,则该框架会实现这些传感器,以便应用仍可以使用它们。</p>
<p>默认实现无法访问其他实现可以访问的所有数据,并且必须在 SoC 上运行,因此它不像其他实现那样精准和省电。设备制造商应尽可能定义自己的融合传感器(旋转矢量传感器、重力传感器和线性加速度传感器,以及<a href="sensor-types.html#game_rotation_vector">游戏旋转矢量</a>传感器等较新的复合传感器),而非依赖该默认实现。此外,设备制造商也可以要求传感器芯片供应商为其提供实现。</p>
<p>默认的传感器融合实现没有相关的维护,且可能导致依赖它的设备无法通过 CTS 验证。</p>
<h3 id="under_the_hood">深入了解</h3>
<p>本部分作为背景信息提供,适用于 Android 开放源代码项目 (AOSP) 框架代码的维护人员,与硬件制造商无关。</p>
<h4 id="jni">JNI</h4>
<p>框架会使用与 <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> 相关联且位于 <code>frameworks/base/core/jni/</code> 目录中的 Java 本机接口 (JNI)。该代码会调用较低级别的原生代码,以获取对相应传感器硬件的访问权限。</p>
<h4 id="native_framework">原生框架</h4>
<p>原生框架在 <code>frameworks/native/</code> 中定义,并提供相当于 <a href="http://developer.android.com/reference/android/hardware/package-summary.html">android.hardware</a> 软件包的原生内容。原生框架会调用 Binder IPC 代理,以获取对传感器专属服务的访问权限。</p>
<h4 id="binder_ipc">Binder IPC</h4>
<p>Binder IPC 代理用于促进跨越进程边界的通信。</p>
<h2 id="hal">HAL</h2>
<p>Sensors Hardware Abstraction Layer (HAL) API 是硬件驱动程序和 Android 框架之间的接口。它包含一个 HAL 接口 sensors.h 和一个我们称之为 sensors.cpp 的 HAL 实现。</p>
<p>接口由 Android 和 AOSP 贡献者定义,并由设备制造商提供实现。</p>
<p>传感器 HAL 接口位于 <code>hardware/libhardware/include/hardware</code> 中。请参阅 <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/sensors.h">sensors.h</a>,了解详情。</p>
<h3 id="release_cycle">版本周期</h3>
<p>HAL 实现通过设置 <code>your_poll_device.common.version</code> 指定实现的 HAL 接口版本。现有 HAL 接口版本在 sensors.h 中定义,相应功能与这些版本绑定在一起。</p>
<p>Android 框架目前支持版本 1.0 和 1.3,不过版本 1.0 很快将不再受支持。本文档介绍了版本 1.3(所有设备均应升级到该版本)的行为。要详细了解如何升级到版本 1.3,请参阅 <a href="versioning.html">HAL 版本弃用</a></p>
<h2 id="kernel_driver">内核驱动程序</h2>
<p>传感器驱动程序可与物理设备进行交互。在某些情况下,HAL 实现和驱动程序是同一软件实体。在其他情况下,硬件集成者会要求传感器芯片制造商提供相应驱动程序,但是它们是用于编写 HAL 实现的驱动程序。</p>
<p>在所有情况下,HAL 实现和内核驱动程序都由硬件制造商负责提供,Android 不提供首选编写方式。</p>
<h2 id="sensor_hub">传感器中枢</h2>
<p>设备的传感器堆栈可视需要添加传感器中枢。在 SoC 可以处于暂停模式时,传感器中枢对执行一些低功耗的低级计算任务非常有用。例如,计步功能或传感器融合功能可以在这些芯片上执行。此外,它也是实施传感器批处理以及为传感器事件添加硬件 FIFO 的理想位置。如需更多信息,请参阅<a href="batching.html">批处理</a></p>
<p class="note"><strong>注意</strong>:要开发采用新传感器或 LED 的新 ContextHub 功能,您还可以使用连接到 HiKey 或 HiKey960 开发板的 <a href="/setup/devices.html#neonkey">Neonkey SensorHub</a></p>
<p>传感器中枢的具体化方式取决于架构。它有时是一个单独的芯片,有时包含在与 SoC 相同的芯片上。传感器中枢的重要特征是,应该包含足够的内存来进行批处理,并消耗极少的电量以便能实现低功耗 Android 传感器。部分传感器中枢包含一个微控制器(用于通用计算)和硬件加速器(用于针对低电耗传感器实现极低功耗计算)。</p>
<p>传感器中枢的架构方式以及与传感器和 SoC(I2C 总线、SPI 总线等)的通信方式并非由 Android 指定,但应该以最大程度减少整体功耗为目标。</p>
<p>有一种方案似乎会对实现的简单性产生重大影响,即从传感器中枢到 SoC 设置两个中断行:一个用于唤醒中断(适用于唤醒传感器),另一个用于非唤醒中断(适用于非唤醒传感器)。</p>
<h2 id="sensors">传感器</h2>
<p>传感器是进行测量操作的物理 MEM 芯片。在很多情况下,同一个芯片上会有多个物理传感器。例如,一些芯片中包含加速度计、陀螺仪和磁力计(此类芯片通常称为 9 轴芯片,因为每个传感器基于 3 个轴提供数据)。</p>
<p>此外,其中的部分芯片还包含用于执行常见计算任务(例如运动状态检测、步数检测以及 9 轴传感器融合)的逻辑。</p>
<p>尽管 CDD 功率和精确度的要求与建议针对的是 Android 传感器而非物理传感器,但这些要求会影响物理传感器的选择。例如,游戏旋转矢量传感器的精确度要求会影响物理陀螺仪的精确度要求。设备制造商负责推算物理传感器的相关要求。</p>
</body></html>