硬件抽象層 (HAL)

HAL 可定義一個標準接口以供硬件供應商實現,這可讓 Android 忽略較低級別的驅動程序實現。藉助 HAL,您可以順利實現相關功能,而不會影響或更改更高級別的系統。HAL 實現會被封裝成模塊,並由 Android 系統適時地加載。

圖 1. HAL 組件
圖 1. HAL 組件

您必須爲您的產品所提供的特定硬件實現相應的 HAL(和驅動程序)。HAL 實現通常會內置在共享庫模塊(.so 文件)中,但 Android 並不要求 HAL 實現與設備驅動程序之間進行標準交互,因此您可以視情況採取適當的做法。不過,要使 Android 系統能夠與您的硬件正確互動,您必須遵守各個特定於硬件的 HAL 接口中定義的規則。

爲了保證 HAL 具有可預測的結構,每個特定於硬件的 HAL 接口都要具有 hardware/libhardware/include/hardware/hardware.h 中定義的屬性。這類接口可讓 Android 系統以一致的方式加載 HAL 模塊的正確版本。HAL 接口包含兩個組件:模塊和設備。

HAL 模塊

一個包含了HAL 實現的模塊被封裝且存儲爲共享庫文件(.so file) 。hardware/libhardware/include/hardware/hardware.h 頭文件會定義一個表示模塊的結構體 (hw_module_t),其中包含模塊的版本、名稱和作者等元數據。Android 會根據這些元數據來找到並正確加載 HAL 模塊。

另外,hw_module_t 結構體還包含指向另一個結構體 hw_module_methods_t 的指針,後面這個結構體會包含一個指向相應模塊的 open 函數的指針。此 open 函數用於與相關硬件(此 HAL 是其抽象形式)建立通信。每個特定於硬件的 HAL 通常都會使用附加信息爲該特定硬件擴展通用的 hw_module_t 結構體。例如,在相機 HAL 中,camera_module_t 結構體會包含一個 hw_module_t 結構體以及其他特定於相機的函數指針:

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;

實現 HAL 並創建模塊結構體時,必須將其命名爲 HAL_MODULE_INFO_SYM。以下是 Nexus 9 音頻 HAL 的示例:

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 = &hal_module_methods,
    },
};

HAL 設備

設備是產品硬件的抽象表示。例如,一個音頻模塊可能包含主音頻設備、USB 音頻設備或藍牙 A2DP 音頻設備。

設備由 hw_device_t 結構體表示。與模塊類似,每類設備都定義了一個通用 hw_device_t 的詳細版本,其中包含指向硬件特定功能的函數指針。例如,audio_hw_device_t 結構體類型會包含指向音頻設備操作的函數指針:


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;

除了這些標準屬性之外,每個特定於硬件的 HAL 接口都可以定義更多的自有功能和要求。有關詳情,請參閱 HAL 參考文檔以及各 HAL 的單獨說明。

編譯 HAL 模塊

HAL 實現會內置在模塊 (.so) 文件中,並由 Android 適時地動態鏈接。您可以爲每個 HAL 實現創建 Android.mk 文件並指向源文件,從而編譯模塊。一般來說,您的共享庫必須以特定格式命名,以方便找到並正確加載。各模塊的命名方案略有不同,但它們都遵循以下通用模式:

<module_type>.<device_name>

要詳細瞭解如何爲每個 HAL 設置模塊編譯,請參閱本網站“移植”部分中特定於 HAL 的文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章