blob: f9c69425a911a29bfdabbf5ad29e95c075ac995c [file] [log] [blame]
<html devsite><head>
<title>旧版 HAL</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>HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,您可以顺利实现相关功能,而不会影响或更改更高级别的系统。本页面介绍了自 Android 8.0 开始已不再支持的旧版架构。对于 Android 8.0 及更高版本,请参阅 <a href="/devices/architecture/hal-types/">HAL 类型</a></p>
<img src="../images/ape_fwk_hal.png"/>
<p class="img-caption"><strong>图 1.</strong> HAL 组件</p>
<p>您必须为您的产品所提供的特定硬件实现相应的 HAL(和驱动程序)。HAL 实现通常会内置在共享库模块(<code>.so</code> 文件)中,但 Android 并不要求 HAL 实现与设备驱动程序之间进行标准交互,因此您可以视情况采取适当的做法。不过,要使 Android 系统能够与您的硬件正确互动,您<strong>必须</strong>遵守各个特定于硬件的 HAL 接口中定义的合同。</p>
<p>为了保证 HAL 具有可预测的结构,每个特定于硬件的 HAL 接口都要具有 <code>hardware/libhardware/include/hardware/hardware.h</code> 中定义的属性。这类接口可让 Android 系统以一致的方式加载 HAL 模块的正确版本。HAL 接口包含两个组件:模块和设备。
</p>
<h2 id="hal-module">HAL 模块</h2>
<p>模块表示被封装且存储为共享库 (<code>.so file</code>) 的 HAL 实现。<code>hardware/libhardware/include/hardware/hardware.h</code> 标头文件会定义一个表示模块的结构体 (<code>hw_module_t</code>),其中包含模块的版本、名称和作者等元数据。Android 会根据这些元数据来找到并正确加载 HAL 模块。</p>
<p>另外,<code>hw_module_t</code> 结构体还包含指向另一个结构体 <code>hw_module_methods_t</code> 的指针,后面这个结构体会包含一个指向相应模块的 open 函数的指针。此 open 函数用于与相关硬件(此 HAL 是其抽象形式)建立通信。每个特定于硬件的 HAL 通常都会使用附加信息为该特定硬件扩展通用的 <code>hw_module_t</code> 结构体。例如,在相机 HAL 中,<code>camera_module_t</code> 结构体会包含一个 <code>hw_module_t</code> 结构体以及其他特定于相机的函数指针:</p>
<pre class="devsite-click-to-copy">
typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
} camera_module_t;
</pre>
<p>实现 HAL 并创建模块结构体时,您必须将其命名为 <code>HAL_MODULE_INFO_SYM</code>。以下是 Nexus 9 音频 HAL 的示例:</p>
<pre class="devsite-click-to-copy">
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "NVIDIA Tegra Audio HAL",
.author = "The Android Open Source Project",
.methods = &amp;hal_module_methods,
},
};
</pre>
<h2 id="hal-device">HAL 设备</h2>
<p>设备是产品硬件的抽象表示。例如,一个音频模块可能包含主音频设备、USB 音频设备或蓝牙 A2DP 音频设备。</p>
<p>设备由 <code>hw_device_t</code> 结构体表示。与模块类似,每类设备都定义了一个通用 <code>hw_device_t</code> 的详细版本,其中包含指向硬件特定功能的函数指针。例如,<code>audio_hw_device_t</code> 结构体类型会包含指向音频设备操作的函数指针:</p>
<pre class="devsite-click-to-copy">
struct audio_hw_device {
struct hw_device_t common;
/**
* used by audio flinger to enumerate what devices are supported by
* each audio_hw_device implementation.
*
* Return value is a bitmask of 1 or more values of audio_devices_t
*/
uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
...
};
typedef struct audio_hw_device audio_hw_device_t;
</pre>
<p>除了这些标准属性之外,每个特定于硬件的 HAL 接口都可以定义更多的自有功能和要求。有关详情,请参阅 <a href="/reference/hal/">HAL 参考文档</a>以及各 HAL 的单独说明。</p>
<h2 id="hal-building">编译 HAL 模块</h2>
<p>HAL 实现会内置在模块 (<code>.so</code>) 文件中,并由 Android 适时地动态链接。您可以为每个 HAL 实现创建 <code>Android.mk</code> 文件并指向源文件,从而编译模块。一般来说,您的共享库必须以特定格式命名,以方便找到并正确加载。各模块的命名方案略有不同,但它们都遵循以下通用模式:<code>&lt;module_type&gt;.&lt;device_name&gt;</code>
</p>
</body></html>