HAL definiuje standardowy interfejs do wdrożenia przez dostawców sprzętu, dzięki czemu system Android może być niezależny od implementacji sterowników niższego poziomu. Korzystanie z HAL pozwala na wdrożenie funkcjonalności bez wpływu lub modyfikacji systemu wyższego poziomu. Na tej stronie opisano starszą architekturę, która nie jest już obsługiwana w systemie Android 8.0. W przypadku Androida 8.0 i nowszych zobacz Omówienie HAL .
Należy zaimplementować odpowiednią warstwę HAL (i sterownik) dla konkretnego sprzętu zapewnianego przez produkt. Implementacje HAL są zazwyczaj wbudowane w moduły bibliotek współdzielonych (pliki .so
), ale ponieważ system Android nie wymaga standardowej interakcji między implementacją HAL a sterownikami urządzeń, możesz zrobić to, co będzie najlepsze w Twojej sytuacji. Aby jednak umożliwić systemowi Android prawidłową interakcję ze sprzętem, należy przestrzegać umowy określonej w każdym interfejsie HAL specyficznym dla sprzętu.
Aby zagwarantować, że warstwy HAL mają przewidywalną strukturę, każdy specyficzny dla sprzętu interfejs HAL ma właściwości zdefiniowane w hardware/libhardware/include/hardware/hardware.h
. Ten interfejs umożliwia systemowi Android ładowanie poprawnych wersji modułów HAL w spójny sposób. Interfejs HAL składa się z dwóch komponentów: modułów i urządzeń.
moduły HAL
Moduł reprezentuje spakowaną implementację HAL, która jest przechowywana jako biblioteka współdzielona ( .so file
). Plik nagłówkowy 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 znalezienia i zał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 otwartej funkcji modułu. Ta otwarta funkcja służy do inicjowania komunikacji ze sprzętem, dla którego warstwa HAL służy jako abstrakcja. Każda specyficzna dla sprzętu warstwa HAL zwykle rozszerza ogólną strukturę hw_module_t
o dodatkowe informacje dotyczące tego konkretnego elementu sprzętu. Na przykład w warstwie HAL kamery struktura camera_module_t
zawiera strukturę hw_module_t
wraz z innymi wskaźnikami funkcji specyficznymi dla kamery:
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;
Kiedy implementujesz warstwę HAL i tworzysz strukturę modułu, musisz nadać jej nazwę HAL_MODULE_INFO_SYM
. Przykład z poziomu dźwięku HAL w Nexusie 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 abstrahuje sprzęt Twojego produktu. Na przykład moduł audio może zawierać główne urządzenie audio, urządzenie audio USB lub urządzenie audio Bluetooth A2DP.
Urządzenie jest reprezentowane przez strukturę hw_device_t
. Podobnie jak moduł, każdy typ urządzenia definiuje szczegółową wersję ogólnego hw_device_t
, który zawiera wskaźniki funkcji dla określonych cech sprzętu. 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, każdy specyficzny dla sprzętu interfejs HAL może definiować więcej własnych funkcji i wymagań. Aby uzyskać szczegółowe informacje, zobacz dokumentację referencyjną HAL , a także indywidualne instrukcje dla każdej warstwy HAL.
Zbuduj moduły HAL
Implementacje HAL są wbudowane w pliki modułów ( .so
) i w razie potrzeby są dynamicznie łączone przez system Android. Możesz budować swoje moduły, tworząc pliki Android.mk
dla każdej implementacji HAL i wskazując pliki źródłowe. Ogólnie rzecz biorąc, biblioteki współdzielone muszą mieć nazwy w określonym formacie, aby można je było poprawnie znaleźć i załadować. Schemat nazewnictwa różni się nieco w zależności od modułu, ale jest zgodny z ogólnym wzorcem: <module_type>.<device_name>
.