Starsze listy HAL

HAL definiuje standardowy interfejs, który dostawcy sprzętu mogą wdrażać, co pozwala Androidowi nie przejmować się implementacjami sterowników niskiego poziomu. Dzięki użyciu HAL możesz wdrażać funkcje bez wpływu na system wyższego poziomu lub jego modyfikacji. Ta strona opisuje starszą architekturę, która nie jest już obsługiwana od Androida 8.0. W przypadku Androida 8.0 lub nowszego zapoznaj się z artykułem Omówienie HAL.

Komponenty HAL

Rysunek 1. Komponenty HAL

Musisz zaimplementować odpowiedni interfejs HAL (oraz sterownik) dla konkretnego sprzętu w Twoim produkcie. Implementacje HAL są zwykle wdrażane w modułach bibliotek współdzielonych (plikach .so), ale ponieważ Android nie narzuca standardowej interakcji między implementacją HAL a sterownikami urządzeń, możesz wybrać rozwiązanie najlepsze w danej sytuacji. Aby jednak umożliwić systemowi Android prawidłową interakcję ze sprzętem, musisz przestrzegać umowy określonej w każdym interfejsie HAL dla konkretnego sprzętu.

Aby zapewnić przewidywalną strukturę interfejsów HAL, każdy interfejs HAL dla konkretnego sprzętu ma właściwości zdefiniowane w hardware/libhardware/include/hardware/hardware.h. Ten interfejs umożliwia systemowi Android wczytywanie prawidłowych wersji modułów HAL w spójny sposób. Interfejs HAL składa się z 2 komponentów: modułów i urządzeń.

Moduły HAL

Moduł reprezentuje zapakowaną implementację HAL, która jest przechowywana jako biblioteka współdzielona (.so file). Plik nagłówka hardware/libhardware/include/hardware/hardware.h definiuje strukturę (hw_module_t), która reprezentuje moduł i zawiera metadane takie jak wersja, nazwa i autor modułu. Android używa tych metadanych do prawidłowego znajdowania i ładowania modułu HAL.

Ponadto struktura hw_module_t zawiera wskaźnik do innej struktury hw_module_methods_t, która zawiera wskaźnik do funkcji otwartej dla modułu. Ta otwarta funkcja służy do inicjowania komunikacji z sprzętem, dla którego HAL pełni rolę abstrakcji. Każdy interfejs HAL dla konkretnego sprzętu zwykle rozszerza ogólny element hw_module_t struct o dodatkowe informacje dotyczące tego konkretnego elementu sprzętowego. Na przykład w komponencie HAL aparatu struktura camera_module_t zawiera strukturę hw_module_t oraz inne wskaźniki funkcji związane z aparatem:

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;

Po zaimplementowaniu HAL i utworzeniu struktury modułu musisz nadać jej nazwę HAL_MODULE_INFO_SYM. Przykład z HAL audio 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,
    },
};

Urządzenia HAL

Urządzenie abstrakcyjne to sprzęt Twojego produktu. Na przykład moduł audio może zawierać podstawowe urządzenie audio, urządzenie audio USB lub urządzenie audio Bluetooth A2DP.

Urządzenie jest reprezentowane przez strukturę hw_device_t. Podobnie jak w przypadku modułów, każdy typ urządzenia definiuje szczegółową wersję ogólnego hw_device_t, która zawiera wskaźniki funkcji dla konkretnych funkcji sprzętowych. Na przykład typ struktury audio_hw_device_t zawiera wskaźniki funkcji do operacji na urządzeniu audio:

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;

Oprócz tych standardowych właściwości interfejs HAL dla konkretnego sprzętu może definiować więcej funkcji i wymagań. Szczegółowe informacje znajdziesz w dokumentacji HAL oraz w instrukcjach dotyczących poszczególnych interfejsów HAL.

Tworzenie modułów HAL

Implementacje HAL są wbudowane w pliki modułów (.so) i w odpowiednich przypadkach są dynamicznie łączone przez Androida. Możesz tworzyć moduły, tworząc pliki Android.mk dla każdej implementacji HAL i wskazując pliki źródłowe. Ogólnie biblioteki udostępnione muszą mieć nazwy w określonym formacie, aby można je było znaleźć i prawidłowo wczytać. Schemat nazewnictwa różni się nieco w zależności od modułu, ale ogólnie jest zgodny z tym wzorcem: <module_type>.<device_name>.

Starsza wersja HAL

Termin „starszy interfejs HAL” odnosi się ogólnie do wszystkich interfejsów HAL starszych niż Android 8.0 (wycofane w Androidzie 8). Większość interfejsów systemu Android (kamera, dźwięk, czujniki itp.) jest zdefiniowana w katalogu „hardware/libhardware/include/hardware” i ma przybliżone wersjonowanie oraz przybliżony stabilny interfejs ABI. Niektóre podsystemy (w tym Wi-Fi, interfejs radiowy i Bluetooth) mają inne niestandardowe interfejsy w `libhardware_legacy` lub są rozproszone w całym kodzie źródłowym. Starsze wersje HAL nie zapewniały gwarancji stabilności.