Legacy-HALs

Ein HAL definiert eine Standardschnittstelle zur Implementierung durch Hardwareanbieter, die es Android ermöglicht, unabhängig von Treiberimplementierungen auf niedrigerer Ebene zu sein. Durch die Verwendung einer HAL können Sie Funktionen implementieren, ohne das übergeordnete System zu beeinträchtigen oder zu ändern. Auf dieser Seite wird die ältere Architektur beschrieben, die ab Android 8.0 nicht mehr unterstützt wird. Informationen zu Android 8.0 und höher finden Sie in der HAL-Übersicht .

HAL-Komponenten

Abbildung 1. HAL-Komponenten

Sie müssen den entsprechenden HAL (und Treiber) für die spezifische Hardware implementieren, die Ihr Produkt bereitstellt. HAL-Implementierungen sind normalerweise in gemeinsam genutzte Bibliotheksmodule ( .so Dateien) integriert. Da Android jedoch keine Standardinteraktion zwischen einer HAL-Implementierung und Gerätetreibern vorschreibt, können Sie das tun, was für Ihre Situation am besten ist. Damit das Android-System jedoch korrekt mit Ihrer Hardware interagieren kann, müssen Sie den in jeder hardwarespezifischen HAL-Schnittstelle definierten Vertrag einhalten.

Um sicherzustellen, dass HALs eine vorhersehbare Struktur haben, verfügt jede hardwarespezifische HAL-Schnittstelle über Eigenschaften, die in hardware/libhardware/include/hardware/hardware.h definiert sind. Diese Schnittstelle ermöglicht es dem Android-System, korrekte Versionen Ihrer HAL-Module auf konsistente Weise zu laden. Eine HAL-Schnittstelle besteht aus zwei Komponenten: Modulen und Geräten.

HAL-Module

Ein Modul stellt Ihre gepackte HAL-Implementierung dar, die als gemeinsam genutzte Bibliothek ( .so file ) gespeichert ist. Die Header-Datei hardware/libhardware/include/hardware/hardware.h definiert eine Struktur ( hw_module_t ), die ein Modul darstellt und Metadaten wie Version, Name und Autor des Moduls enthält. Android verwendet diese Metadaten, um das HAL-Modul korrekt zu finden und zu laden.

Darüber hinaus enthält die Struktur hw_module_t einen Zeiger auf eine andere Struktur, hw_module_methods_t , die einen Zeiger auf eine offene Funktion für das Modul enthält. Diese offene Funktion wird verwendet, um die Kommunikation mit der Hardware zu initiieren, für die die HAL als Abstraktion dient. Jeder hardwarespezifische HAL erweitert normalerweise die generische hw_module_t Struktur um zusätzliche Informationen für diese bestimmte Hardware. Beispielsweise enthält in der Kamera-HAL die Struktur camera_module_t eine Struktur hw_module_t zusammen mit anderen kameraspezifischen Funktionszeigern:

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;

Wenn Sie eine HAL implementieren und die Modulstruktur erstellen, müssen Sie sie HAL_MODULE_INFO_SYM nennen. Beispiel aus dem Audio-HAL des Nexus 9:

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-Geräte

Ein Gerät abstrahiert die Hardware Ihres Produkts. Beispielsweise kann ein Audiomodul ein primäres Audiogerät, ein USB-Audiogerät oder ein Bluetooth-A2DP-Audiogerät enthalten.

Ein Gerät wird durch die Struktur hw_device_t dargestellt. Ähnlich wie bei einem Modul definiert jeder Gerätetyp eine detaillierte Version des generischen hw_device_t , das Funktionszeiger für bestimmte Funktionen der Hardware enthält. Beispielsweise enthält der Strukturtyp audio_hw_device_t Funktionszeiger auf Audiogeräteoperationen:

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;

Zusätzlich zu diesen Standardeigenschaften kann jede hardwarespezifische HAL-Schnittstelle weitere eigene Funktionen und Anforderungen definieren. Einzelheiten finden Sie in der HAL-Referenzdokumentation sowie in den einzelnen Anweisungen für jede HAL.

Erstellen Sie HAL-Module

HAL-Implementierungen sind in Moduldateien ( .so ) integriert und werden bei Bedarf von Android dynamisch verknüpft. Sie können Ihre Module erstellen, indem Sie Android.mk Dateien für jede Ihrer HAL-Implementierungen erstellen und auf Ihre Quelldateien verweisen. Im Allgemeinen müssen Ihre gemeinsam genutzten Bibliotheken in einem bestimmten Format benannt werden, damit sie ordnungsgemäß gefunden und geladen werden können. Das Benennungsschema variiert geringfügig von Modul zu Modul, folgt aber dem allgemeinen Muster: <module_type>.<device_name> .

Legacy-HAL

Der Begriff Legacy-HAL bezieht sich im Großen und Ganzen auf alle HALs vor Android 8.0 (in Android 8 veraltet). Der Großteil der Android-Systemschnittstellen (Kamera, Audio, Sensoren usw.) ist unter „hardware/libhardware/include/hardware“ definiert und verfügt über eine grobe Versionierung und einen ungefähr stabilen ABI. Einige Subsysteme (einschließlich Wi-Fi, Radio Interface Layer und Bluetooth) verfügen über andere nicht standardisierte Schnittstellen in „libhardware_legacy“ oder sind in der gesamten Codebasis verstreut. Ältere HALs boten nie feste Stabilitätsgarantien.